From 1d52234b1aae2b6766a1e8c0d0ee4901a2104eb0 Mon Sep 17 00:00:00 2001 From: nogueiraguh Date: Thu, 5 Mar 2026 11:55:05 -0300 Subject: [PATCH] refactor: reorganize Reports and Downloads tabs, update README Move report history/status table to Reports tab. Simplify Downloads tab to show only completed reports with expandable file browser grouped by category. Add CIS Level description tooltip and fix log expand persisting during report generation polling. --- README.md | 6 ++--- frontend/index.html | 59 ++++++++++++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 6906cab..279fc4d 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ The platform combines security compliance scanning, AI-powered chat with **RAG ( - **Level 1**: Essential security controls that can be implemented with minimal impact on operations. Recommended as baseline for all organizations. - **Level 2**: Advanced security controls that may restrict functionality or require more effort to implement. Recommended for high-security environments. - **Multiple output formats**: HTML summary, CSV per section/finding, JSON summary, optional XLSX -- **File browser**: all generated files stored per report, browsable and downloadable individually -- **Tenancy filter**: filter reports by tenancy in the Downloads tab +- **Report history**: full execution history with status, tenancy filter, and download actions (HTML/JSON) in the Reports tab +- **File browser**: dedicated Downloads tab with expandable cards per completed report, files grouped by category (Summary, CIS Findings, OBP, Raw Data, etc.) - Region filtering with multi-select - Real-time progress tracking with phase-based progress bar - **CIS Engine auto-update**: check for new versions of `cis_reports.py` from Oracle's GitHub repository and update with one click (admin only). Custom patches are automatically reapplied after update @@ -576,7 +576,7 @@ All models include OCID mapping for `us-ashburn-1`. For other regions, use the " | Version | Date | Changes | |---------|------|---------| -| **v1.8** | 2026-03 | CIS Engine auto-update from Oracle GitHub with automatic patch reapplication, version check UI card (admin), new `/api/cis-engine/*` endpoints, report file listing and individual download endpoints | +| **v1.8** | 2026-03 | CIS Engine auto-update from Oracle GitHub with automatic patch reapplication, version check UI card (admin), new `/api/cis-engine/*` endpoints, report file listing and individual download endpoints, reorganized Reports tab (execution history + status) and Downloads tab (file browser only with expandable cards per report), CIS Level description tooltip, persistent log expand during report generation | | **v1.7** | 2026-03 | Oracle official CIS report engine (replaces lightweight checker), granular report parameters (Level, OBP, Raw Data, Redact), per-report file storage with category browser, tenancy filter in Downloads, individual file download | | **v1.6** | 2026-03 | Granular CIS MCP server (12 per-section scan tools: IAM, Networking, Compute, Logging/Monitoring, Storage, Asset Management), chat memory compaction with LLM-based summarization, GenAI tool use loop fix (accumulated conversation), chat thinking indicator, auto-registered CIS MCP server | | **v1.5** | 2026-03 | MCP Tool Use in Chat (GenAI function calling with auto tool discovery + execution via MCP SDK), multi-table ADB vector search, preview chunks before embedding, enriched embeddings with tenancy/regions/compartments, searchable dropdowns, editable vector tables, orphaned report cleanup on restart | diff --git a/frontend/index.html b/frontend/index.html index 49a1ff7..07b0ca3 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -218,7 +218,7 @@ const S={user:null,token:null,tab:'chat',msgs:[],sid:null,reports:[],ociCfg:[],g chatPrompts:[],editingPrompt:null,trackingReportId:null,ociRegions:{},rptSelRegions:[],rptRegionsOpen:false,rptRegionFilter:'', rptOciOpen:false,rptOciFilter:'',rptOciVal:'',rptRselOpen:false,rptRselFilter:'',rptRselVal:'',ociFormRegOpen:false,ociFormRegFilter:'',ociFormRegVal:'', rptLevel:2,rptObp:false,rptRaw:false,rptRedact:false,reportFiles:{},dlExpandedRid:null,dlTenancyFilter:'', - cisVer:null,cisCheckResult:null,cisUpdating:false}; + cisVer:null,cisCheckResult:null,cisUpdating:false,rptHistFilter:''}; const API='/api'; async function $api(p,o={}){const h={...(o.headers||{})};if(S.token)h['Authorization']='Bearer '+S.token; @@ -406,7 +406,7 @@ function rReport(){const comp=S.reports.filter(r=>r.status==='completed'); const m=last.match(/\[(\d+)\/(\d+)\]/);const pct=m?Math.round((parseInt(m[1])/parseInt(m[2]))*100):0; progressHtml=`
${rProgressCard('running',last,pct,lines,S.trackingReportId)}
`; if(!_rptPollTimer)startRptPoll()} - if(!comp.length)return`${progressHtml}
📊 Compliance Reports
📄

Nenhum relatório gerado ainda.

${rRunRpt()}`; + if(!comp.length)return`${progressHtml}
📊 Compliance Reports
📄

Nenhum relatório gerado ainda.

${rRunRpt()}${rReportHistory()}`; const lt=comp[0]; const selRpt=S.rptRselVal?comp.find(r=>r.id===S.rptRselVal):lt; if(!S.rptRselVal)S.rptRselVal=lt.id; @@ -421,7 +421,7 @@ ${S.rptRselOpen?`
Nenhum relatório encontrado
'} `:''} -${rRunRpt()}`} +${rRunRpt()}${rReportHistory()}`} function rRunRpt(){if(S.user?.role==='viewer')return''; const selTags=S.rptSelRegions.map(r=>`${r}×`).join(' '); const f=S.rptRegionFilter.toLowerCase(); @@ -509,7 +509,9 @@ async function pollRptProgress(){if(!S.trackingReportId)return stopRptPoll(); if(ft.includes('writing cis reports'))pct=75; if(ft.includes('best practices'))pct=85; if(ft.includes('finished'))pct=100; - el.innerHTML=rProgressCard(p.status,last,pct,lines,S.trackingReportId)} + const wasOpen=el.querySelector('details[open]')!==null; + el.innerHTML=rProgressCard(p.status,last,pct,lines,S.trackingReportId); + if(wasOpen){const d=el.querySelector('details');if(d)d.open=true}} if(p.status==='completed'||p.status==='failed'||p.status==='cancelled'){stopRptPoll();S.trackingReportId=null;S.reports=await $api('/reports');R()}}catch(e){}} async function cancelRpt(rid){if(!confirm('Cancelar este relatório?'))return; try{await $api('/reports/'+rid+'/cancel',{method:'POST'});stopRptPoll();S.trackingReportId=null;S.reports=await $api('/reports');R()}catch(e){alert('Erro: '+e.message)}} @@ -525,33 +527,52 @@ function rProgressCard(status,lastStep,pct,lines,rid){ ${lines.length>1?`
Ver log completo
${lines.join('\n')}
`:''} `} -/* ── Downloads ── */ -function rDl(){ +/* ── Report History (inside Reports tab) ── */ +function rReportHistory(){ const tenancies=[...new Set(S.reports.map(r=>r.tenancy_name))].sort(); - const filtered=S.dlTenancyFilter?S.reports.filter(r=>r.tenancy_name===S.dlTenancyFilter):S.reports; - return`
-
- -${tenancies.map(t=>``).join('')} +${tenancies.map(t=>``).join('')} ${filtered.length} report(s)
-
-
+
TenancyLevelOpçõesStatusExecutadoConcluídoArquivosAções
${filtered.map(r=>{ const opts=[];if(r.obp_checks)opts.push('OBP');if(r.raw_data)opts.push('Raw');if(r.redact_output)opts.push('Redact'); - const isExp=S.dlExpandedRid===r.id; - const fHtml=isExp&&S.reportFiles[r.id]?renderFileList(r.id,S.reportFiles[r.id]):''; return` - - -${isExp?``:''}`}).join('')}
TenancyLevelOpçõesStatusExecutadoConcluídoAções
${r.tenancy_name} ${r.level||2} ${opts.join(', ')||'—'} ${r.status==='cancelled'?'cancelado':r.status} ${r.created_at||'—'} ${r.completed_at||'—'}${r.status==='completed'?``:'—'}${r.status==='completed'?` `:r.status==='running'?``:'—'}
${fHtml}
-${!filtered.length?'
📂

Nenhum relatório.

':''}
`} +${r.status==='completed'?` `:r.status==='running'?``:'—'}`}).join('')} +${!filtered.length?'

Nenhum relatório.

':''}`} + +/* ── Downloads (file browser only) ── */ +function rDl(){ + const comp=S.reports.filter(r=>r.status==='completed'); + const tenancies=[...new Set(comp.map(r=>r.tenancy_name))].sort(); + const filtered=S.dlTenancyFilter?comp.filter(r=>r.tenancy_name===S.dlTenancyFilter):comp; + return`
+
+ +${filtered.length} report(s)
+
+${!filtered.length?'
📂

Nenhum relatório concluído.

':` +
${filtered.map(r=>{ + const isExp=S.dlExpandedRid===r.id; + const fHtml=isExp&&S.reportFiles[r.id]?renderFileList(r.id,S.reportFiles[r.id]):''; + return`
+
+
${r.tenancy_name}Level ${r.level||2} — ${r.created_at}
+${isExp?'▲ Ocultar':'▼ Ver Arquivos'}
+${isExp?fHtml:''}
`}).join('')}
`}`} async function toggleFiles(rid){if(S.dlExpandedRid===rid){S.dlExpandedRid=null;R();return} S.dlExpandedRid=rid;if(!S.reportFiles[rid]){try{S.reportFiles[rid]=await $api('/reports/'+rid+'/files')}catch(e){S.reportFiles[rid]=[]}}R()} function renderFileList(rid,files){if(!files.length)return'
Nenhum arquivo encontrado
';