Spaces:
Sleeping
Sleeping
| <template> | |
| <div id="app" class="saap-app"> | |
| <!-- SAAP Header --> | |
| <header class="saap-header"> | |
| <div class="header-content"> | |
| <div class="logo-section"> | |
| <h1 class="saap-heading-2"> | |
| <span class="logo-text">SAAP</span> | |
| <span class="logo-subtitle">Multi-Agent Platform</span> | |
| </h1> | |
| </div> | |
| <div class="status-section"> | |
| <div class="connection-status" :class="connectionStatusClass"> | |
| <div class="status-dot"></div> | |
| <span>{{ connectionStatusText }}</span> | |
| </div> | |
| <div class="agent-summary"> | |
| <span class="agent-count">{{ activeAgents }}/{{ totalAgents }}</span> | |
| <span class="agent-label">Agents Active</span> | |
| </div> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content Area - Direct Dashboard --> | |
| <main class="saap-main"> | |
| <SaapDashboard /> | |
| </main> | |
| <!-- Footer --> | |
| <footer class="saap-footer"> | |
| <div class="footer-content"> | |
| <span class="footer-text"> | |
| SAAP v1.0.0 • | |
| Built with Vue.js • | |
| Powered by colossus Server | |
| </span> | |
| <span class="footer-build"> | |
| Build: {{ buildDate }} | |
| </span> | |
| </div> | |
| </footer> | |
| </div> | |
| </template> | |
| <script> | |
| import { ref, computed, onMounted } from 'vue' | |
| import SaapDashboard from './components/SaapDashboard.vue' | |
| import saapApi from './services/saapApi.js' | |
| export default { | |
| name: 'SaapApp', | |
| components: { | |
| SaapDashboard | |
| }, | |
| setup() { | |
| // Reactive state | |
| const isConnected = ref(false) | |
| const totalAgents = ref(0) | |
| const activeAgents = ref(0) | |
| // Computed properties | |
| const connectionStatusClass = computed(() => ({ | |
| 'status-connected': isConnected.value, | |
| 'status-disconnected': !isConnected.value | |
| })) | |
| const connectionStatusText = computed(() => | |
| isConnected.value ? 'Connected' : 'Disconnected' | |
| ) | |
| const buildDate = computed(() => | |
| new Date().toLocaleDateString('de-DE') | |
| ) | |
| // Load agents data from API using saapApi service | |
| const loadAgentsStats = async () => { | |
| try { | |
| console.log('🔄 Loading agents stats via API service...') | |
| const response = await saapApi.getAgents() | |
| console.log('📦 API Response:', response) | |
| // Backend returns {agents: [...], total: N, active: N} | |
| if (response && response.agents) { | |
| totalAgents.value = response.total || response.agents.length | |
| activeAgents.value = response.active || response.agents.filter(a => a.status === 'active').length | |
| isConnected.value = true | |
| console.log(`✅ Loaded ${totalAgents.value} agents (${activeAgents.value} active)`) | |
| } else { | |
| console.warn('⚠️ Unexpected API response format:', response) | |
| isConnected.value = false | |
| } | |
| } catch (error) { | |
| console.error('❌ Failed to load agents stats:', error) | |
| isConnected.value = false | |
| } | |
| } | |
| // Initialize app | |
| onMounted(() => { | |
| console.log('🚀 SAAP Dashboard initialized') | |
| loadAgentsStats() | |
| // Refresh stats every 3 seconds | |
| setInterval(loadAgentsStats, 3000) | |
| }) | |
| return { | |
| isConnected, | |
| totalAgents, | |
| activeAgents, | |
| connectionStatusClass, | |
| connectionStatusText, | |
| buildDate | |
| } | |
| } | |
| } | |
| </script> | |
| <style scoped> | |
| /* SAAP App Layout */ | |
| .saap-app { | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| background: var(--saap-gray-50); | |
| } | |
| /* Header Styles */ | |
| .saap-header { | |
| background: white; | |
| border-bottom: 1px solid var(--saap-gray-200); | |
| box-shadow: var(--saap-shadow-sm); | |
| position: sticky; | |
| top: 0; | |
| z-index: 50; | |
| } | |
| .header-content { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: var(--saap-space-4) var(--saap-space-6); | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| } | |
| /* Logo Section */ | |
| .logo-section { | |
| display: flex; | |
| align-items: center; | |
| } | |
| .logo-text { | |
| background: linear-gradient(135deg, var(--saap-primary-600), var(--saap-secondary-600)); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| font-weight: var(--saap-font-bold); | |
| margin-right: var(--saap-space-2); | |
| } | |
| .logo-subtitle { | |
| font-size: var(--saap-text-base); | |
| font-weight: var(--saap-font-normal); | |
| color: var(--saap-gray-600); | |
| } | |
| /* Status Section */ | |
| .status-section { | |
| display: flex; | |
| align-items: center; | |
| gap: var(--saap-space-6); | |
| } | |
| .connection-status { | |
| display: flex; | |
| align-items: center; | |
| gap: var(--saap-space-2); | |
| padding: var(--saap-space-2) var(--saap-space-4); | |
| border-radius: var(--saap-radius-lg); | |
| font-size: var(--saap-text-sm); | |
| font-weight: var(--saap-font-medium); | |
| } | |
| .status-dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: var(--saap-radius-full); | |
| transition: background-color var(--saap-transition-base); | |
| } | |
| .status-connected { | |
| background: rgba(34, 197, 94, 0.1); | |
| color: var(--saap-secondary-700); | |
| } | |
| .status-connected .status-dot { | |
| background: var(--saap-secondary-500); | |
| } | |
| .status-disconnected { | |
| background: rgba(239, 68, 68, 0.1); | |
| color: var(--saap-accent-700); | |
| } | |
| .status-disconnected .status-dot { | |
| background: var(--saap-accent-500); | |
| } | |
| /* Agent Summary */ | |
| .agent-summary { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| text-align: center; | |
| } | |
| .agent-count { | |
| font-size: var(--saap-text-xl); | |
| font-weight: var(--saap-font-bold); | |
| color: var(--saap-primary-600); | |
| } | |
| .agent-label { | |
| font-size: var(--saap-text-xs); | |
| color: var(--saap-gray-500); | |
| text-transform: uppercase; | |
| letter-spacing: 0.5px; | |
| } | |
| /* Main Content */ | |
| .saap-main { | |
| flex: 1; | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| width: 100%; | |
| } | |
| /* Footer */ | |
| .saap-footer { | |
| background: white; | |
| border-top: 1px solid var(--saap-gray-200); | |
| padding: var(--saap-space-4) var(--saap-space-6); | |
| } | |
| .footer-content { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| font-size: var(--saap-text-xs); | |
| color: var(--saap-gray-500); | |
| } | |
| /* Responsive Design */ | |
| @media (max-width: 768px) { | |
| .header-content { | |
| flex-direction: column; | |
| gap: var(--saap-space-4); | |
| padding: var(--saap-space-4); | |
| } | |
| .logo-subtitle { | |
| display: none; | |
| } | |
| .status-section { | |
| gap: var(--saap-space-4); | |
| } | |
| .footer-content { | |
| flex-direction: column; | |
| gap: var(--saap-space-2); | |
| text-align: center; | |
| } | |
| .saap-main { | |
| padding: var(--saap-space-4); | |
| } | |
| } | |
| </style> | |