diff --git a/backend/src/main/java/com/park/utmstack/domain/compliance/UtmComplianceReportConfig.java b/backend/src/main/java/com/park/utmstack/domain/compliance/UtmComplianceReportConfig.java index 66a9ed1a5..68a461af7 100644 --- a/backend/src/main/java/com/park/utmstack/domain/compliance/UtmComplianceReportConfig.java +++ b/backend/src/main/java/com/park/utmstack/domain/compliance/UtmComplianceReportConfig.java @@ -7,6 +7,7 @@ import com.park.utmstack.domain.chart_builder.UtmDashboard; import com.park.utmstack.domain.chart_builder.UtmDashboardVisualization; import com.park.utmstack.domain.chart_builder.types.query.FilterType; +import com.park.utmstack.domain.compliance.enums.ComplianceStatus; import com.park.utmstack.domain.compliance.enums.ComplianceType; import com.park.utmstack.domain.compliance.types.RequestParamFilter; import com.park.utmstack.domain.shared_types.DataColumn; @@ -92,6 +93,10 @@ public class UtmComplianceReportConfig implements Serializable { @Column(name = "config_report_name", length = 50) private String configReportName; + @Enumerated(EnumType.STRING) + @Column(name = "config_report_status", length = 25) + private ComplianceStatus configReportStatus; + @Transient @JsonSerialize @JsonDeserialize @@ -105,6 +110,8 @@ public class UtmComplianceReportConfig implements Serializable { @JoinColumn(name = "dashboard_id", referencedColumnName = "id", insertable = false, updatable = false) private UtmDashboard associatedDashboard; + + @Transient @JsonSerialize @JsonDeserialize @@ -336,4 +343,12 @@ public String getConfigRemediation() { public void setConfigRemediation(String configRemediation) { this.configRemediation = configRemediation; } + + public ComplianceStatus getConfigReportStatus() { + return configReportStatus; + } + + public void setConfigReportStatus(ComplianceStatus complianceStatus) { + this.configReportStatus = complianceStatus; + } } diff --git a/backend/src/main/java/com/park/utmstack/domain/compliance/enums/ComplianceStatus.java b/backend/src/main/java/com/park/utmstack/domain/compliance/enums/ComplianceStatus.java new file mode 100644 index 000000000..36bfe48c9 --- /dev/null +++ b/backend/src/main/java/com/park/utmstack/domain/compliance/enums/ComplianceStatus.java @@ -0,0 +1,5 @@ +package com.park.utmstack.domain.compliance.enums; +public enum ComplianceStatus { + COMPLAINT, + NON_COMPLAINT +} diff --git a/backend/src/main/java/com/park/utmstack/repository/compliance/UtmComplianceReportConfigRepository.java b/backend/src/main/java/com/park/utmstack/repository/compliance/UtmComplianceReportConfigRepository.java index bd43a8b31..5c498e7bf 100644 --- a/backend/src/main/java/com/park/utmstack/repository/compliance/UtmComplianceReportConfigRepository.java +++ b/backend/src/main/java/com/park/utmstack/repository/compliance/UtmComplianceReportConfigRepository.java @@ -1,6 +1,8 @@ package com.park.utmstack.repository.compliance; import com.park.utmstack.domain.compliance.UtmComplianceReportConfig; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; @@ -16,7 +18,6 @@ /** * Spring Data repository for the ComplianceTemplate entity. */ -@SuppressWarnings("unused") @Repository public interface UtmComplianceReportConfigRepository extends JpaRepository, JpaSpecificationExecutor { @@ -28,4 +29,19 @@ public interface UtmComplianceReportConfigRepository extends JpaRepository reportIds); + + @Query(value = "SELECT cfg FROM UtmComplianceReportConfig cfg " + + "JOIN cfg.section sec " + + "LEFT JOIN cfg.associatedDashboard d " + + "WHERE (:standardId IS NULL OR sec.standardId = :standardId) " + + "AND (:solution IS NULL OR lower(cfg.configSolution) LIKE %:solution%) " + + "AND (:sectionId IS NULL OR sec.id = :sectionId) " + + "AND (:search IS NULL OR lower(cfg.configReportName) LIKE %:search% OR d.name LIKE %:search%)") + Page getReportsByFilters( + @Param("standardId") Long standardId, + @Param("solution") String solution, + @Param("sectionId") Long sectionId, + @Param("search") String search, + Pageable pageable); + } diff --git a/backend/src/main/java/com/park/utmstack/service/compliance/config/UtmComplianceReportConfigService.java b/backend/src/main/java/com/park/utmstack/service/compliance/config/UtmComplianceReportConfigService.java index b42d68dc7..833ec2dfc 100644 --- a/backend/src/main/java/com/park/utmstack/service/compliance/config/UtmComplianceReportConfigService.java +++ b/backend/src/main/java/com/park/utmstack/service/compliance/config/UtmComplianceReportConfigService.java @@ -1,12 +1,22 @@ package com.park.utmstack.service.compliance.config; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.park.utmstack.domain.chart_builder.UtmDashboard; +import com.park.utmstack.domain.chart_builder.UtmDashboardVisualization; +import com.park.utmstack.domain.chart_builder.UtmVisualization; +import com.park.utmstack.domain.chart_builder.types.ChartType; import com.park.utmstack.domain.compliance.UtmComplianceReportConfig; import com.park.utmstack.domain.compliance.UtmComplianceStandard; import com.park.utmstack.domain.compliance.UtmComplianceStandardSection; +import com.park.utmstack.domain.compliance.enums.ComplianceStatus; import com.park.utmstack.repository.compliance.UtmComplianceReportConfigRepository; import com.park.utmstack.service.chart_builder.UtmDashboardService; +import com.park.utmstack.service.chart_builder.UtmDashboardVisualizationService; +import com.park.utmstack.service.elasticsearch.ElasticsearchService; import com.park.utmstack.util.UtilPagination; -import com.park.utmstack.util.exceptions.UtmPageNumberNotSupported; +import com.park.utmstack.util.chart_builder.elasticsearch_dsl.requests.RequestDsl; +import com.park.utmstack.util.exceptions.UtmElasticsearchException; +import org.opensearch.client.opensearch.core.SearchResponse; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -17,6 +27,7 @@ import org.springframework.util.StringUtils; import javax.persistence.EntityManager; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -29,17 +40,24 @@ public class UtmComplianceReportConfigService { private final UtmDashboardService dashboardService; private final UtmComplianceStandardService standardService; private final UtmComplianceStandardSectionService standardSectionService; + + private final UtmDashboardVisualizationService dashboardVisualizationService; + + private final ElasticsearchService elasticsearchService; private final EntityManager em; public UtmComplianceReportConfigService(UtmComplianceReportConfigRepository complianceReportConfigRepository, UtmDashboardService dashboardService, UtmComplianceStandardService standardService, UtmComplianceStandardSectionService standardSectionService, + UtmDashboardVisualizationService dashboardVisualizationService, ElasticsearchService elasticsearchService, EntityManager em) { this.complianceReportConfigRepository = complianceReportConfigRepository; this.dashboardService = dashboardService; this.standardService = standardService; this.standardSectionService = standardSectionService; + this.dashboardVisualizationService = dashboardVisualizationService; + this.elasticsearchService = elasticsearchService; this.em = em; } @@ -81,61 +99,24 @@ public void deleteReportsByStandardIdAndIdNotIn(Long standardId, List repo } public Page getReportsByFilters(Long standardId, String solution, Long sectionId, - String search, Pageable pageable) { - StringBuilder script = new StringBuilder( - "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 " + - "LEFT JOIN utm_dashboard d ON cfg.dashboard_id = d.id"); - - StringBuilder countScript = new StringBuilder( - "SELECT COUNT(cfg.id) 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 " + - "LEFT JOIN utm_dashboard d ON cfg.dashboard_id = d.id"); - - boolean hasWhere = false; - - if (standardId != null) { - hasWhere = true; - script.append(" WHERE st.id = ").append(standardId); - countScript.append(" WHERE st.id = ").append(standardId); - } + String search, Boolean expandDashboard, Boolean setStatus, Pageable pageable) throws UtmElasticsearchException { - if (StringUtils.hasText(solution)) { - String condition = "cfg.config_solution ILIKE '%" + solution + "%'"; - script.append(hasWhere ? " AND " : " WHERE ").append(condition); - countScript.append(hasWhere ? " AND " : " WHERE ").append(condition); - hasWhere = true; - } + Page page = complianceReportConfigRepository.getReportsByFilters(standardId, solution, sectionId, search, pageable); - if (sectionId != null) { - String condition = "sec.id = " + sectionId; - script.append(hasWhere ? " AND " : " WHERE ").append(condition); - countScript.append(hasWhere ? " AND " : " WHERE ").append(condition); - } - - if (StringUtils.hasText(search)) { - String condition = "(cfg.config_report_name ILIKE '%" + search + "%' OR d.name ILIKE '%" + search + "%')"; - script.append(hasWhere ? " AND " : " WHERE ").append(condition); - countScript.append(hasWhere ? " AND " : " WHERE ").append(condition); + if (expandDashboard != null && expandDashboard) { + for (UtmComplianceReportConfig report : page) { + dashboardVisualizationService.findAllByIdDashboard(report.getDashboardId()).ifPresent(report::setDashboard); + } } - if (StringUtils.hasText(solution)) { - pageable.getSort(); - String sortField = pageable.getSort().iterator().next().getProperty(); - String sortDirection = pageable.getSort().iterator().next().getDirection().name(); - script.append(" ORDER BY ").append(sortField).append(" ").append(sortDirection); + if (setStatus) { + for (UtmComplianceReportConfig report : page) { + report.setConfigReportStatus(this.getStatus(report.getAssociatedDashboard())); + } } - List results = em.createNativeQuery(script.toString(), UtmComplianceReportConfig.class) - .setFirstResult(UtilPagination.getFirstForNativeSql(pageable.getPageSize(), pageable.getPageNumber())) - .setMaxResults(pageable.getPageSize()) - .getResultList(); - - long total = ((Number) em.createNativeQuery(countScript.toString()).getSingleResult()).longValue(); + return page; - return new PageImpl<>(results, pageable, total); } @@ -143,10 +124,6 @@ public void deleteAllByConfigSolutionAndSectionIdAndDashboardId(String configSol complianceReportConfigRepository.deleteAllByConfigSolutionAndStandardSectionIdAndDashboardId(configSolution, sectionId, dashboardId); } - /** - * @param reports - * @param override - */ public void importReports(List reports, boolean override) throws Exception { final String ctx = CLASSNAME + ".importReports"; try { @@ -200,4 +177,23 @@ public void importReports(List reports, boolean overr throw new Exception(msg); } } + + private ComplianceStatus getStatus(UtmDashboard dashboard) throws UtmElasticsearchException { + List dashboardVisualizations = dashboardVisualizationService.findAllByIdDashboard(dashboard.getId()) + .orElse(Collections.emptyList()); + + UtmVisualization visualization = dashboardVisualizations.stream().filter(d -> d.getVisualization().getChartType().equals(ChartType.LIST_CHART) + || d.getVisualization().getChartType().equals(ChartType.TABLE_CHART)) + .map(UtmDashboardVisualization::getVisualization) + .findFirst() + .orElse(null); + + if(Objects.nonNull(visualization)){ + RequestDsl requestQuery = new RequestDsl(visualization); + SearchResponse result = elasticsearchService.search(requestQuery.getSearchSourceBuilderForCount().build(), ObjectNode.class); + return result.hits().total().value() > 0 ? ComplianceStatus.COMPLAINT : ComplianceStatus.NON_COMPLAINT; + } else { + return ComplianceStatus.NON_COMPLAINT; + } + } } diff --git a/backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/requests/RequestDsl.java b/backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/requests/RequestDsl.java index c3464b65d..cf2fc07d3 100644 --- a/backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/requests/RequestDsl.java +++ b/backend/src/main/java/com/park/utmstack/util/chart_builder/elasticsearch_dsl/requests/RequestDsl.java @@ -57,6 +57,27 @@ public SearchRequest.Builder getSearchSourceBuilder() throws UtmElasticsearchExc } } + public SearchRequest.Builder getSearchSourceBuilderForCount() throws UtmElasticsearchException { + final String ctx = CLASSNAME + ".getSearchSourceBuilderForCount"; + try { + List filters = visualization.getFilterType(); + + if (CollectionUtils.isEmpty(filters)) + filters = new ArrayList<>(); + + searchRequestBuilder.query(SearchUtil.toQuery(filters)); + + searchRequestBuilder.size(0); // Esto asegura que no se devuelvan los documentos + searchRequestBuilder.trackTotalHits(TrackHits.of(t -> t.enabled(true))); + + return searchRequestBuilder; + } catch (Exception e) { + throw new UtmElasticsearchException(ctx + ": " + e.getMessage()); + } + } + + + /** * Build an aggregation section for an elasticsearch dsl request * diff --git a/backend/src/main/java/com/park/utmstack/web/rest/compliance/config/UtmComplianceReportConfigResource.java b/backend/src/main/java/com/park/utmstack/web/rest/compliance/config/UtmComplianceReportConfigResource.java index 339fcf0f7..6c0de0b6a 100644 --- a/backend/src/main/java/com/park/utmstack/web/rest/compliance/config/UtmComplianceReportConfigResource.java +++ b/backend/src/main/java/com/park/utmstack/web/rest/compliance/config/UtmComplianceReportConfigResource.java @@ -173,17 +173,14 @@ public ResponseEntity> getReportsByFilters(@Requ @RequestParam(required = false) String solution, @RequestParam(required = false) Long sectionId, @RequestParam(required = false) String search, - @RequestParam(required = false) Boolean expandDashboard, + @RequestParam(required = false, defaultValue = "false") Boolean setStatus, + @RequestParam(required = false, defaultValue = "false") Boolean expandDashboard, Pageable pageable) { final String ctx = CLASS_NAME + ".getReportsByFilters"; try { - Page page = complianceReportConfigService.getReportsByFilters(standardId, solution, sectionId, search, pageable); + Page page = complianceReportConfigService.getReportsByFilters(standardId, solution, sectionId, search, expandDashboard, setStatus, pageable); - if (!Objects.isNull(expandDashboard) && expandDashboard) { - for (UtmComplianceReportConfig report : page) - dashboardVisualizationService.findAllByIdDashboard(report.getDashboardId()).ifPresent(report::setDashboard); - } - HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/utm-asset-groups/searchGroupsByFilter"); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/report-config/get-by-filters"); return ResponseEntity.ok().headers(headers).body(page.getContent()); } catch (Exception e) { String msg = ctx + ": " + e.getMessage(); diff --git a/backend/src/main/resources/config/liquibase/changelog/20250127001_add_compliance_data.xml b/backend/src/main/resources/config/liquibase/changelog/20250127001_add_compliance_data.xml index f89af0dad..f4f474e21 100644 --- a/backend/src/main/resources/config/liquibase/changelog/20250127001_add_compliance_data.xml +++ b/backend/src/main/resources/config/liquibase/changelog/20250127001_add_compliance_data.xml @@ -1217,8 +1217,53 @@ INSERT INTO utm_compliance_report_config (id, config_solution, config_report_columns, config_report_req_body, config_report_req_params, config_report_resource_url, config_report_request_type, config_report_pageable, config_report_filter_by_time, config_report_data_origin, config_report_export_csv_url, standard_section_id, config_report_editable, dashboard_id, config_type, config_url, config_report_note, config_report_name, config_report_remediation) VALUES (898, e'The Windows Access to Shared Resources Report provides detailed logs of events where users or systems access shared resources, such as files, folders, printers, or shared drives. This report is critical for ensuring compliance with Real-Time Alerting and Monitoring within the Banking Audit framework, as shared resource access can expose sensitive data if not properly monitored.
• Regulatory Compliance: Aligns with the GLBA Safeguards Rule, ensuring oversight of shared resource access to protect sensitive financial systems and customer data.
• Access Control Monitoring: Supports compliance with PCI DSS Requirement 7, ensuring that access to shared resources is restricted to authorized users and activities are logged.
• Real-Time Alerting: Captures and notifies administrators immediately of unauthorized or suspicious access to shared resources, enabling rapid response to potential threats.
• Incident Detection: Identifies patterns of unauthorized access, excessive data downloads, or unusual access times, which may indicate insider threats or compromised accounts.
• Audit Readiness: Tracks all access events to shared resources, ensuring compliance with frameworks like SOC2 Type 2 and ISO 27001, demonstrating secure resource-sharing practices.', null, null, null, null, null, null, null, null, null, 1000017, true, 1000013, 'TEMPLATE', null, null, 'Windows Access to Shared Resources', null); SELECT setval('utm_compliance_report_config_id_seq', (SELECT MAX(id) FROM utm_compliance_report_config)); - + -- dashboard menu + + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (104, 'Threat Activity', 'dashboard/render/7/threat-activity', 100, 1, 7, 10, true, false, null, null); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (107, 'Windows Systems', 'dashboard/render/226/windows-systems', 100, 1, 226, 40, true, false, null, null); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (108, 'O365 Overview', 'dashboard/render/13/o365-overview', 100, 1, 13, 50, true, false, null, 'O365'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (109, 'O365 Exchange', 'dashboard/render/234/o365-exchange', 100, 1, 234, 60, true, false, null, 'O365'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (110, 'O365 Active Directory', 'dashboard/render/271/o365-active-directory', 100, 1, 271, 70, true, false, null, 'O365'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (111, 'O365 SharePoint', 'dashboard/render/221/o365-sharepoint', 100, 1, 221, 80, true, false, null, 'O365'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (112, 'O365 Threat Intelligence', 'dashboard/render/11/o365-threat-intelligence', 100, 1, 11, 90, true, false, null, 'O365'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (113, 'VMware System', 'dashboard/render/223/vmware-system', 100, 1, 223, 100, true, false, null, 'VMWARE'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (114, 'AWS Cloud', 'dashboard/render/227/aws-cloud', 100, 1, 227, 110, false, false, null, 'AWS_IAM_USER'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (116, 'Meraki System', 'dashboard/render/236/meraki-system', 100, 1, 236, 130, true, false, null, 'MERAKI'); + INSERT INTO utm_menu (id, name, url, parent_id, type, dashboard_id, position, menu_active, menu_action, menu_icon, module_name_short) VALUES (117, 'Bitdefender System', 'dashboard/render/238/bitdefender-system', 100, 1, 238, 140, false, false, null, 'BITDEFENDER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (104, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (104, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (107, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (107, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (108, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (108, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (109, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (109, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (110, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (110, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (111, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (111, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (112, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (112, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (113, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (113, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (114, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (114, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (116, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (116, 'ROLE_USER'); + + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (117, 'ROLE_ADMIN'); + INSERT INTO utm_menu_authority (menu_id, authority_name) VALUES (117, 'ROLE_USER'); ]]> diff --git a/frontend/src/app/compliance/compliance-report-viewer/compliance-report-viewer.component.html b/frontend/src/app/compliance/compliance-report-viewer/compliance-report-viewer.component.html index 767631fb4..cdc74e88f 100644 --- a/frontend/src/app/compliance/compliance-report-viewer/compliance-report-viewer.component.html +++ b/frontend/src/app/compliance/compliance-report-viewer/compliance-report-viewer.component.html @@ -61,7 +61,7 @@
-
+
diff --git a/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.html b/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.html index 063375b7d..60fd591db 100644 --- a/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.html +++ b/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.html @@ -36,7 +36,7 @@
Security Control Name @@ -46,9 +46,8 @@
- + @@ -109,8 +108,7 @@
-
diff --git a/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.ts b/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.ts index 544f70530..de16b4535 100644 --- a/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.ts +++ b/frontend/src/app/compliance/compliance-reports-view/compliance-reports-view.component.ts @@ -38,11 +38,11 @@ export class ComplianceReportsViewComponent implements OnInit, OnChanges, OnDest page = 0; totalItems = 0; sortEvent: SortEvent = { - column: 'config_report_name', + column: 'configReportName', direction: 'desc' }; destroy$: Subject = new Subject(); - sort = 'config_report_name,desc'; + sort = 'configReportName,desc'; search: string; constructor(private reportsService: CpReportsService, @@ -64,6 +64,7 @@ export class ComplianceReportsViewComponent implements OnInit, OnChanges, OnDest standardId: this.section.standardId, sectionId: this.section.id, expandDashboard: true, + setStatus: true, sort: this.sort, search: this.search ? this.search : null, })), diff --git a/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.html b/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.html index bd08bc4b7..c7cc8609a 100644 --- a/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.html +++ b/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.html @@ -1,11 +1,11 @@
-
+
Status: - - {{ report.status === 'complaint' ? 'Compliant' : 'Non compliant' }} + {{ isComplaint() ? 'Compliant' : 'Non compliant' }}
@@ -58,7 +58,17 @@
- + +
+ Compliance note: +
+ +
+ +
+
+ +
Compliance remediation:
diff --git a/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.ts b/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.ts index f3264b95e..6aada72eb 100644 --- a/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.ts +++ b/frontend/src/app/compliance/compliance-reports-view/components/compliance-report-detail/compliance-report-detail.component.ts @@ -11,6 +11,7 @@ import {TimeWindowsService} from '../../../shared/components/utm-cp-section/time import {ComplianceReportType} from '../../../shared/type/compliance-report.type'; import {ExportPdfService} from "../../../../shared/services/util/export-pdf.service"; import {UtmToastService} from "../../../../shared/alert/utm-toast.service"; +import {ComplianceStatusEnum} from "../../../shared/enums/compliance-status.enum"; @Component({ selector: 'app-compliance-report-detail', @@ -20,7 +21,7 @@ import {UtmToastService} from "../../../../shared/alert/utm-toast.service"; export class ComplianceReportDetailComponent implements OnInit { request = { page: 0, - size: 10000, + size: 10, sort: 'order,asc', 'idDashboard.equals': 0 }; @@ -28,6 +29,7 @@ export class ComplianceReportDetailComponent implements OnInit { compliance$!: Observable; csvExport = false; printFormat = false; + ComplianceStatusEnum = ComplianceStatusEnum; constructor(private utmRenderVisualization: UtmRenderVisualization, private runVisualization: RunVisualizationService, @@ -135,4 +137,8 @@ export class ComplianceReportDetailComponent implements OnInit { }); } + isComplaint() { + return this.report.configReportStatus === ComplianceStatusEnum.COMPLAINT + || (this.report.configReportNote && this.report.configReportNote !== ''); + } } diff --git a/frontend/src/app/compliance/compliance-reports-view/components/compliance-status/compliance-status.component.html b/frontend/src/app/compliance/compliance-reports-view/components/compliance-status/compliance-status.component.html index e18bd530e..29ddfc846 100644 --- a/frontend/src/app/compliance/compliance-reports-view/components/compliance-status/compliance-status.component.html +++ b/frontend/src/app/compliance/compliance-reports-view/components/compliance-status/compliance-status.component.html @@ -1,22 +1,22 @@ -
- + - {{ compliance.status ? 'Compliant' : 'Non compliant' }} + {{ isComplaint() ? 'Compliant' : 'Non compliant' }}
-
+
- {{ compliance.status || (report.configReportNote && report.configReportNote !== '') ? 'Compliant' : 'Non compliant' }} + {{ isComplaint() ? 'Compliant' : 'Non compliant' }} - diff --git a/frontend/src/app/shared/components/utm/util/modal-add-note/modal-add-note.component.ts b/frontend/src/app/shared/components/utm/util/modal-add-note/modal-add-note.component.ts index 5632da501..9be81346b 100644 --- a/frontend/src/app/shared/components/utm/util/modal-add-note/modal-add-note.component.ts +++ b/frontend/src/app/shared/components/utm/util/modal-add-note/modal-add-note.component.ts @@ -1,8 +1,9 @@ import {Component, Input, OnInit} from '@angular/core'; import {NgbActiveModal} from '@ng-bootstrap/ng-bootstrap'; +import {ComplianceStatusEnum} from '../../../../../compliance/shared/enums/compliance-status.enum'; +import {CpReportsService} from '../../../../../compliance/shared/services/cp-reports.service'; import {ComplianceReportType} from '../../../../../compliance/shared/type/compliance-report.type'; -import {CpReportsService} from "../../../../../compliance/shared/services/cp-reports.service"; -import {UtmToastService} from "../../../../alert/utm-toast.service"; +import {UtmToastService} from '../../../../alert/utm-toast.service'; @Component({ selector: 'app-modal-add-note', @@ -11,6 +12,7 @@ import {UtmToastService} from "../../../../alert/utm-toast.service"; }) export class ModalAddNoteComponent implements OnInit { @Input() report: ComplianceReportType; + @Input() isComplaint: boolean; header: string; message: string; confirmBtnText: string; @@ -20,6 +22,7 @@ export class ModalAddNoteComponent implements OnInit { textType: 'warning' | 'danger'; hideBtnCancel = false; note = ''; + ComplianceStatusEnum = ComplianceStatusEnum; constructor(private activeModal: NgbActiveModal, private reportsService: CpReportsService, @@ -30,9 +33,10 @@ export class ModalAddNoteComponent implements OnInit { } confirm() { - this.setReport(); + this.reportsService.update({ ...this.report, + configReportNote: !this.isComplaint ? this.note : null, dashboard: [], }).subscribe(response => { this.toastService.showSuccessBottom('Note added successfully'); @@ -51,8 +55,4 @@ export class ModalAddNoteComponent implements OnInit { cancel() { this.activeModal.dismiss('cancel'); } - - setReport(){ - this.report.status === 'non_complaint' ? this.report.configReportNote = this.note : this.report.configReportNote = ''; - } }