Evolução da plataforma: dashboard com gráficos, notificações, relatórios automáticos, ícones Lucide local e melhorias gerais

- Dashboard com 5 gráficos Chart.js (execuções, status, custo, agentes, pipelines)
- Sistema de notificações com polling, badge e Browser Notification API
- Relatórios MD automáticos para execuções de agentes e pipelines (data/reports/)
- Lucide local (v0.475.0) com nomes de ícones atualizados e refreshIcons centralizado
- Correção de ícones icon-only (padding CSS sobrescrito por btn-sm)
- Cards de agentes e pipelines com botões alinhados na base (flex column)
- Terminal com busca, download, cópia e auto-scroll toggle
- Histórico com export CSV, retry, paginação e truncamento de texto
- Webhooks com edição e teste inline
- Duplicação de agentes e export/import JSON
- Rate limiting, CORS, correlação de requests e health check no backend
- Escrita atômica em JSON (temp + rename) e store de notificações
- Tema claro/escuro com toggle e persistência em localStorage
- Atalhos de teclado 1-9 para navegação entre seções
This commit is contained in:
Frederico Castro
2026-02-26 20:41:17 -03:00
parent 69943f91be
commit da22154f66
26 changed files with 18375 additions and 67 deletions

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Agents Orchestrator</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.7/dist/chart.umd.min.js"></script>
<link rel="stylesheet" href="css/styles.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
@@ -104,13 +105,35 @@
<span>Sistema</span>
</button>
<button class="btn btn--ghost btn--icon-text" id="import-agent-btn" type="button">
<i data-lucide="upload"></i>
<i data-lucide="file-down"></i>
<span>Importar</span>
</button>
<button class="btn btn--primary btn--icon-text" id="new-agent-btn" type="button">
<i data-lucide="plus"></i>
<span>Novo Agente</span>
</button>
<button id="theme-toggle" class="btn btn--icon" title="Alternar tema">
<i data-lucide="sun" class="theme-icon-light"></i>
<i data-lucide="moon" class="theme-icon-dark"></i>
</button>
<div class="notification-wrapper">
<button id="notification-bell" class="btn btn--icon" title="Notificações">
<i data-lucide="bell"></i>
<span id="notification-badge" class="notification-badge hidden">0</span>
</button>
<div id="notification-panel" class="notification-panel hidden">
<div class="notification-panel-header">
<h3>Notificações</h3>
<div class="notification-panel-actions">
<button id="mark-all-read" class="btn btn--ghost btn--sm">Marcar lidas</button>
<button id="clear-notifications" class="btn btn--ghost btn--sm">Limpar</button>
</div>
</div>
<div id="notification-list" class="notification-list">
<div class="notification-empty">Nenhuma notificação</div>
</div>
</div>
</div>
</div>
</header>
@@ -138,7 +161,7 @@
</article>
<article class="metric-card">
<div class="metric-card-icon metric-card-icon--purple">
<i data-lucide="play-circle"></i>
<i data-lucide="circle-play"></i>
</div>
<div class="metric-card-body">
<span class="metric-card-label">Execuções Hoje</span>
@@ -174,6 +197,46 @@
</article>
</div>
<div class="charts-row">
<div class="chart-container">
<div class="chart-header">
<h3>Execuções</h3>
<select id="chart-period" class="select-sm">
<option value="7">7 dias</option>
<option value="14">14 dias</option>
<option value="30">30 dias</option>
</select>
</div>
<canvas id="executions-chart"></canvas>
</div>
<div class="chart-container">
<div class="chart-header">
<h3>Custo (USD)</h3>
</div>
<canvas id="cost-chart"></canvas>
</div>
</div>
<div class="charts-row charts-row--triple">
<div class="chart-container">
<div class="chart-header">
<h3>Status</h3>
</div>
<canvas id="status-chart"></canvas>
</div>
<div class="chart-container">
<div class="chart-header">
<h3>Top Agentes</h3>
</div>
<canvas id="agents-chart"></canvas>
</div>
<div class="chart-container">
<div class="chart-header">
<h3>Taxa de Sucesso</h3>
</div>
<canvas id="success-rate-chart"></canvas>
</div>
</div>
<div class="dashboard-grid">
<div class="card">
<div class="card-header">
@@ -424,6 +487,32 @@
</button>
</div>
</div>
<div class="terminal-action-toolbar">
<div class="terminal-toolbar-left">
<button id="terminal-search-toggle" class="btn btn--ghost btn--sm" title="Buscar (Ctrl+F)">
<i data-lucide="search" style="width:14px;height:14px"></i>
</button>
<button id="terminal-download" class="btn btn--ghost btn--sm" title="Baixar saída">
<i data-lucide="download" style="width:14px;height:14px"></i>
</button>
<button id="terminal-copy" class="btn btn--ghost btn--sm" title="Copiar saída">
<i data-lucide="copy" style="width:14px;height:14px"></i>
</button>
</div>
<div class="terminal-toolbar-right">
<label class="terminal-toggle-label">
<input type="checkbox" id="terminal-autoscroll" checked>
<span>Auto-scroll</span>
</label>
</div>
</div>
<div id="terminal-search-bar" class="terminal-search-bar hidden">
<input type="text" id="terminal-search-input" placeholder="Buscar no terminal..." class="input input--sm">
<span id="terminal-search-count" class="terminal-search-count">0/0</span>
<button id="terminal-search-prev" class="btn btn--ghost btn--sm"></button>
<button id="terminal-search-next" class="btn btn--ghost btn--sm"></button>
<button id="terminal-search-close" class="btn btn--ghost btn--sm"></button>
</div>
<div class="approval-notification" id="approval-notification" hidden></div>
<div class="terminal-output" id="terminal-output" role="log" aria-live="polite" aria-label="Saída do terminal">
<div class="terminal-welcome">
@@ -471,6 +560,10 @@
</select>
</div>
<div class="toolbar-actions">
<button id="history-export-csv" class="btn btn--ghost btn--sm" title="Exportar CSV">
<i data-lucide="file-spreadsheet" style="width:14px;height:14px"></i>
Exportar
</button>
<button class="btn btn-ghost btn-sm btn-danger" id="history-clear-btn" type="button">
<i data-lucide="trash-2"></i>
Limpar Histórico
@@ -552,6 +645,64 @@
<span class="system-info-label">Tempo Online</span>
<span class="system-info-value font-mono" id="info-uptime">Carregando...</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Tema Atual</span>
<span class="system-info-value" id="info-current-theme">Escuro</span>
</li>
</ul>
</div>
</div>
<div class="card">
<div class="card-header">
<h2 class="card-title">Atalhos do Teclado</h2>
</div>
<div class="card-body">
<ul class="system-info-list">
<li class="system-info-item">
<span class="system-info-label">Fechar modal</span>
<span class="system-info-value font-mono">Esc</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Novo agente (em Agentes)</span>
<span class="system-info-value font-mono">N</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Dashboard</span>
<span class="system-info-value font-mono">1</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Agentes</span>
<span class="system-info-value font-mono">2</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Tarefas</span>
<span class="system-info-value font-mono">3</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Agendamentos</span>
<span class="system-info-value font-mono">4</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Pipelines</span>
<span class="system-info-value font-mono">5</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Terminal</span>
<span class="system-info-value font-mono">6</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Histórico</span>
<span class="system-info-value font-mono">7</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Webhooks</span>
<span class="system-info-value font-mono">8</span>
</li>
<li class="system-info-item">
<span class="system-info-label">Configurações</span>
<span class="system-info-value font-mono">9</span>
</li>
</ul>
</div>
</div>
@@ -778,11 +929,11 @@
<span>Revisão OWASP</span>
</button>
<button class="template-btn" type="button" data-template="Refatorar o código para melhorar legibilidade, manutenibilidade e aderência às boas práticas. Manter comportamento funcional intacto.">
<i data-lucide="wand-2"></i>
<i data-lucide="wand"></i>
<span>Refatorar Código</span>
</button>
<button class="template-btn" type="button" data-template="Escrever testes unitários e de integração abrangentes. Garantir cobertura dos casos de sucesso, erro e edge cases.">
<i data-lucide="test-tube-2"></i>
<i data-lucide="test-tube"></i>
<span>Escrever Testes</span>
</button>
<button class="template-btn" type="button" data-template="Documentar o código com JSDoc/docstrings, README atualizado, exemplos de uso e descrição de APIs públicas.">
@@ -994,7 +1145,7 @@
<div class="modal modal--sm">
<div class="modal-header">
<div class="confirm-modal-icon" id="confirm-modal-icon">
<i data-lucide="alert-triangle"></i>
<i data-lucide="triangle-alert"></i>
</div>
<h2 class="modal-title" id="confirm-modal-title">Confirmar Ação</h2>
<button class="modal-close" type="button" aria-label="Fechar modal" data-modal-close="confirm-modal-overlay">
@@ -1060,7 +1211,7 @@
<div class="modal-footer">
<button class="btn btn--ghost" type="button" data-modal-close="import-modal-overlay">Cancelar</button>
<button class="btn btn--primary btn--icon-text" type="button" id="import-confirm-btn">
<i data-lucide="upload"></i>
<i data-lucide="file-down"></i>
<span>Importar</span>
</button>
</div>
@@ -1116,7 +1267,7 @@
<div class="toast-container" id="toast-container" aria-live="assertive" aria-atomic="false" role="region" aria-label="Notificações"></div>
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.js"></script>
<script src="js/lucide.js"></script>
<script src="js/api.js"></script>
<script src="js/utils.js"></script>
<script src="js/components/toast.js"></script>
@@ -1130,9 +1281,10 @@
<script src="js/components/settings.js"></script>
<script src="js/components/history.js"></script>
<script src="js/components/webhooks.js"></script>
<script src="js/components/notifications.js"></script>
<script src="js/app.js"></script>
<script>
lucide.createIcons();
Utils.refreshIcons();
App.init();
</script>
</body>