mio dashboard docs.kosmonum.space/mio/
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

v21

+505 -1253
+505 -1253
dashboard.html
··· 3 3 <head> 4 4 <meta charset="UTF-8"> 5 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 - <title>Cluster Dashboard</title> 6 + <title>MIO Dashboard</title> 7 7 <style> 8 8 * { 9 9 margin: 0; ··· 15 15 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; 16 16 background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); 17 17 min-height: 100vh; 18 - padding: 40px 20px; 19 - } 20 - 21 - .container { 22 - max-width: 100%; 23 - margin: 0 auto; 18 + padding: 20px; 24 19 } 25 20 21 + /* Header Styles */ 26 22 .header { 27 - margin-bottom: 40px; 28 - max-width: 1400px; 29 - margin-left: auto; 30 - margin-right: auto; 31 - } 32 - 33 - .header h1 { 34 - font-size: 32px; 35 - color: #1a1a1a; 36 - font-weight: 600; 37 - margin-bottom: 8px; 38 - } 39 - 40 - .header p { 41 - color: #666; 42 - font-size: 14px; 43 - } 44 - 45 - .clusters-list { 46 - display: flex; 47 - flex-direction: column; 48 - gap: 16px; 49 - max-width: 100%; 50 - } 51 - 52 - .cluster-card { 53 23 background: white; 54 - border-radius: 12px; 55 - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); 56 - transition: all 0.3s ease; 57 - border: 1px solid #e8e8e8; 58 - overflow: hidden; 59 - } 60 - 61 - .cluster-card:hover { 62 - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); 63 - border-color: #d0d0d0; 64 - } 65 - 66 - .cluster-header { 67 - padding: 16px 20px; 68 - display: flex; 69 - align-items: center; 70 - gap: 20px; 71 - cursor: pointer; 72 - user-select: none; 73 - } 74 - 75 - .cluster-header:hover { 76 - background: #f9f9f9; 77 - } 78 - 79 - .expand-icon { 80 - width: 24px; 81 - height: 24px; 24 + padding: 16px 24px; 25 + border-radius: 8px; 82 26 display: flex; 83 27 align-items: center; 84 - justify-content: center; 85 - font-size: 18px; 86 - transition: transform 0.3s ease; 87 - color: #666; 88 - flex-shrink: 0; 89 - } 90 - 91 - .cluster-card.expanded .expand-icon { 92 - transform: rotate(180deg); 28 + justify-content: space-between; 29 + margin-bottom: 24px; 30 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); 93 31 } 94 32 95 - .heartbeat { 96 - width: 28px; 97 - height: 28px; 33 + .header-left { 98 34 display: flex; 99 35 align-items: center; 100 - justify-content: center; 101 - font-size: 20px; 102 - animation: heartbeat 1.5s ease-in-out infinite; 103 - flex-shrink: 0; 104 - } 105 - 106 - .heartbeat.healthy { 107 - color: #10b981; 108 - } 109 - 110 - .heartbeat.warning { 111 - color: #f59e0b; 112 - } 113 - 114 - .heartbeat.critical { 115 - color: #ef4444; 116 - } 117 - 118 - @keyframes heartbeat { 119 - 0%, 100% { 120 - transform: scale(1); 121 - opacity: 1; 122 - } 123 - 25% { 124 - transform: scale(1.2); 125 - opacity: 0.8; 126 - } 127 - 50% { 128 - transform: scale(1); 129 - opacity: 1; 130 - } 131 - 75% { 132 - transform: scale(1.1); 133 - opacity: 0.9; 134 - } 36 + gap: 12px; 135 37 } 136 38 137 - .cluster-name { 138 - font-size: 16px; 39 + .header-title { 40 + font-size: 18px; 139 41 font-weight: 600; 140 - color: #1a1a1a; 141 - min-width: 140px; 142 - flex-shrink: 0; 42 + color: #333; 143 43 } 144 44 145 - .metrics-container { 146 - display: flex; 147 - align-items: center; 148 - gap: 16px; 149 - flex: 1; 45 + .butterfly-icon { 46 + font-size: 24px; 150 47 } 151 48 152 - .metric { 153 - display: flex; 154 - flex-direction: column; 155 - gap: 4px; 156 - min-width: 120px; 157 - } 158 - 159 - .metric-label { 160 - font-size: 11px; 161 - font-weight: 600; 162 - color: #666; 163 - text-transform: uppercase; 164 - letter-spacing: 0.5px; 165 - } 166 - 167 - .metric-content { 49 + .header-right { 168 50 display: flex; 169 51 align-items: center; 170 - gap: 8px; 52 + gap: 12px; 171 53 } 172 54 173 - .metric-value { 55 + .btn { 56 + padding: 8px 12px; 57 + border: none; 58 + background: #f0f2f5; 59 + color: #333; 60 + border-radius: 6px; 61 + cursor: pointer; 174 62 font-size: 16px; 175 - font-weight: 700; 176 - color: #1a1a1a; 177 - min-width: 40px; 178 - } 179 - 180 - .metric-bar { 181 - width: 60px; 182 - height: 5px; 183 - background: #e8e8e8; 184 - border-radius: 3px; 185 - overflow: hidden; 186 - } 187 - 188 - .metric-bar-fill { 189 - height: 100%; 190 - border-radius: 3px; 191 - transition: width 0.3s ease; 63 + transition: all 0.2s ease; 64 + display: flex; 65 + align-items: center; 66 + justify-content: center; 67 + gap: 6px; 192 68 } 193 69 194 - .metric-bar-fill.usage { 195 - background: linear-gradient(90deg, #3b82f6 0%, #1e40af 100%); 70 + .btn:hover { 71 + background: #e4e6eb; 72 + transform: translateY(-1px); 196 73 } 197 74 198 - .metric-bar-fill.saturation { 199 - background: linear-gradient(90deg, #f59e0b 0%, #d97706 100%); 75 + .btn-primary { 76 + background: #f0f2f5; 77 + font-weight: 500; 200 78 } 201 79 202 - .metric-bar-fill.error { 203 - background: linear-gradient(90deg, #ef4444 0%, #dc2626 100%); 204 - } 205 - 206 - .metric-bar-fill.latency { 207 - background: linear-gradient(90deg, #8b5cf6 0%, #6d28d9 100%); 208 - } 209 - 210 - .menu-container { 211 - position: relative; 212 - flex-shrink: 0; 213 - margin-left: auto; 214 - } 215 - 216 - .menu-button { 217 - background: none; 218 - border: 2px solid #e8e8e8; 80 + .btn-icon { 219 81 width: 36px; 220 82 height: 36px; 221 - border-radius: 8px; 222 - cursor: pointer; 223 - font-size: 20px; 83 + padding: 0; 224 84 display: flex; 225 85 align-items: center; 226 86 justify-content: center; 227 - transition: all 0.2s ease; 228 - color: #999; 229 - padding: 0; 87 + border-radius: 6px; 230 88 } 231 89 232 - .menu-button:hover { 233 - background: #f9f9f9; 234 - border-color: #d0d0d0; 235 - color: #1a1a1a; 90 + .avatar-btn { 91 + border-radius: 50%; 92 + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); 93 + color: white; 94 + font-weight: 600; 95 + position: relative; 96 + cursor: pointer; 236 97 } 237 98 238 - .menu-button:active { 239 - background: #efefef; 240 - transform: scale(0.95); 99 + /* Dropdown Menus */ 100 + .dropdown { 101 + position: relative; 102 + display: inline-block; 241 103 } 242 104 243 - .menu-dropdown { 105 + .dropdown-menu { 244 106 position: absolute; 245 107 top: 100%; 246 108 right: 0; 247 109 background: white; 248 - border: 1px solid #e8e8e8; 249 - border-radius: 8px; 250 - margin-top: 8px; 110 + border-radius: 6px; 251 111 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 252 112 min-width: 160px; 253 - opacity: 0; 254 - visibility: hidden; 255 - transform: translateY(-8px); 256 - transition: all 0.2s ease; 257 113 z-index: 1000; 114 + display: none; 115 + margin-top: 4px; 116 + overflow: hidden; 258 117 } 259 118 260 - .menu-dropdown.active { 261 - opacity: 1; 262 - visibility: visible; 263 - transform: translateY(0); 119 + .dropdown-menu.active { 120 + display: block; 264 121 } 265 122 266 - .menu-item { 123 + .dropdown-item { 124 + padding: 10px 16px; 267 125 display: flex; 268 126 align-items: center; 269 - gap: 12px; 270 - padding: 12px 16px; 127 + gap: 8px; 128 + color: #333; 129 + cursor: pointer; 130 + transition: background 0.2s ease; 271 131 border: none; 272 132 background: none; 273 - cursor: pointer; 274 - font-size: 14px; 275 - color: #1a1a1a; 276 133 width: 100%; 277 134 text-align: left; 278 - transition: background 0.2s ease; 135 + font-size: 14px; 279 136 } 280 137 281 - .menu-item:hover { 282 - background: #f9f9f9; 138 + .dropdown-item:hover { 139 + background: #f0f2f5; 283 140 } 284 141 285 - .menu-item:first-child { 286 - border-radius: 8px 8px 0 0; 142 + .dropdown-item.danger { 143 + color: #dc3545; 287 144 } 288 145 289 - .menu-item:last-child { 290 - border-radius: 0 0 8px 8px; 146 + .dropdown-item.danger:hover { 147 + background: #ffe5e5; 291 148 } 292 149 293 - .menu-item.danger { 294 - color: #ef4444; 150 + /* Instances Container */ 151 + .instances-container { 152 + max-width: 1200px; 153 + margin: 0 auto; 295 154 } 296 155 297 - .menu-item.danger:hover { 298 - background: #fee2e2; 156 + /* Instance Card */ 157 + .instance { 158 + background: white; 159 + padding: 16px 20px; 160 + border-radius: 8px; 161 + margin-bottom: 12px; 162 + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); 163 + transition: all 0.2s ease; 164 + display: grid; 165 + grid-template-columns: auto 1fr auto auto; 166 + grid-template-rows: auto auto; 167 + gap: 12px 12px; 168 + align-items: start; 169 + } 170 + 171 + .instance:hover { 172 + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12); 299 173 } 300 174 301 - .menu-item-icon { 302 - font-size: 16px; 175 + /* Heartbeat on its own row */ 176 + .heartbeat { 177 + font-size: 20px; 178 + animation: pulse 1.5s ease-in-out infinite; 179 + width: 24px; 180 + height: 24px; 303 181 display: flex; 304 182 align-items: center; 305 183 justify-content: center; 306 - width: 20px; 184 + flex-shrink: 0; 185 + grid-column: 1; 186 + grid-row: 1; 307 187 } 308 188 309 - .cluster-content { 310 - max-height: 0; 311 - overflow: hidden; 312 - transition: max-height 0.3s ease; 189 + .heartbeat.healthy { 190 + color: #28a745; 313 191 } 314 192 315 - .cluster-card.expanded .cluster-content { 316 - max-height: 2000px; 193 + .heartbeat.warning { 194 + color: #ffc107; 317 195 } 318 196 319 - .instances-container { 320 - padding: 0 20px 20px 20px; 321 - border-top: 1px solid #f0f0f0; 322 - display: flex; 323 - flex-direction: column; 324 - gap: 12px; 197 + .heartbeat.critical { 198 + color: #dc3545; 325 199 } 326 200 327 - .instance-item { 328 - padding: 12px 16px; 329 - background: #f9f9f9; 330 - border-radius: 8px; 331 - border: 1px solid #f0f0f0; 332 - display: flex; 333 - align-items: center; 334 - gap: 16px; 201 + @keyframes pulse { 202 + 0%, 100% { opacity: 1; } 203 + 50% { opacity: 0.5; } 335 204 } 336 205 337 - .instance-name-small { 338 - font-size: 14px; 206 + /* First line: name + tags + menu */ 207 + .instance-name { 339 208 font-weight: 500; 340 - color: #1a1a1a; 341 - min-width: 120px; 342 - flex-shrink: 0; 343 - } 344 - 345 - .metrics-container-small { 209 + color: #333; 346 210 display: flex; 347 211 align-items: center; 348 - gap: 16px; 349 - flex: 1; 212 + grid-column: 2; 213 + grid-row: 1; 214 + text-transform: uppercase; 215 + font-size: 13px; 216 + letter-spacing: 0.5px; 217 + height: 24px; 350 218 } 351 219 352 - .metric-small { 220 + /* Tags container */ 221 + .instance-tags { 353 222 display: flex; 354 - flex-direction: column; 355 - gap: 2px; 356 - min-width: 100px; 223 + gap: 8px; 224 + align-items: center; 225 + grid-column: 3; 226 + grid-row: 1; 227 + justify-self: end; 228 + height: 24px; 357 229 } 358 230 359 - .metric-label-small { 360 - font-size: 10px; 361 - font-weight: 600; 362 - color: #999; 231 + .tag { 232 + display: inline-flex; 233 + align-items: center; 234 + padding: 4px 8px; 235 + background: #f0f2f5; 236 + color: #333; 237 + border-radius: 4px; 238 + font-size: 11px; 239 + font-weight: 500; 240 + cursor: help; 241 + transition: all 0.2s ease; 242 + position: relative; 363 243 text-transform: uppercase; 364 - letter-spacing: 0.4px; 365 244 } 366 245 367 - .metric-content-small { 368 - display: flex; 369 - align-items: center; 370 - gap: 6px; 246 + .tag:hover { 247 + background: #e4e6eb; 371 248 } 372 249 373 - .metric-value-small { 374 - font-size: 14px; 250 + /* Tag tooltip */ 251 + .tag::before { 252 + content: attr(data-label); 253 + position: absolute; 254 + bottom: -24px; 255 + left: 50%; 256 + transform: translateX(-50%); 257 + background: #333; 258 + color: white; 259 + padding: 4px 8px; 260 + border-radius: 4px; 261 + font-size: 10px; 375 262 font-weight: 600; 376 - color: #1a1a1a; 377 - min-width: 35px; 263 + white-space: nowrap; 264 + opacity: 0; 265 + pointer-events: none; 266 + transition: opacity 0.2s ease; 267 + z-index: 100; 378 268 } 379 269 380 - .metric-bar-small { 381 - width: 50px; 382 - height: 4px; 383 - background: #e8e8e8; 384 - border-radius: 2px; 385 - overflow: hidden; 270 + .tag:hover::before { 271 + opacity: 1; 386 272 } 387 273 388 - .metric-bar-fill-small { 389 - height: 100%; 390 - border-radius: 2px; 274 + /* Metrics on second line */ 275 + .metrics { 276 + display: flex; 277 + gap: 24px; 278 + grid-column: 2 / 4; 279 + grid-row: 2; 391 280 } 392 281 393 - .instance-menu-container { 282 + .metric { 283 + display: flex; 284 + flex-direction: column; 285 + gap: 4px; 286 + flex: 1; 287 + min-width: 80px; 394 288 position: relative; 395 - flex-shrink: 0; 396 - margin-left: auto; 397 289 } 398 290 399 - .instance-menu-button { 400 - background: none; 401 - border: 2px solid #e8e8e8; 402 - width: 32px; 403 - height: 32px; 404 - border-radius: 6px; 291 + .metric-bar { 292 + height: 8px; 293 + background: #e9ecef; 294 + border-radius: 4px; 295 + overflow: hidden; 405 296 cursor: pointer; 406 - font-size: 16px; 407 - display: flex; 408 - align-items: center; 409 - justify-content: center; 410 - transition: all 0.2s ease; 411 - color: #999; 412 - padding: 0; 297 + position: relative; 413 298 } 414 299 415 - .instance-menu-button:hover { 416 - background: #f0f0f0; 417 - border-color: #d0d0d0; 418 - color: #1a1a1a; 419 - } 420 - 421 - .instance-menu-button:active { 422 - background: #e0e0e0; 423 - transform: scale(0.95); 300 + .metric-fill { 301 + height: 100%; 302 + border-radius: 4px; 303 + transition: width 0.3s ease; 424 304 } 425 305 426 - .instance-menu-dropdown { 427 - position: absolute; 428 - top: 100%; 429 - right: 0; 430 - background: white; 431 - border: 1px solid #e8e8e8; 432 - border-radius: 8px; 433 - margin-top: 6px; 434 - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); 435 - min-width: 150px; 436 - opacity: 0; 437 - visibility: hidden; 438 - transform: translateY(-8px); 439 - transition: all 0.2s ease; 440 - z-index: 1001; 306 + .metric-utilization .metric-fill { 307 + background: linear-gradient(90deg, #4a90e2 0%, #357abd 100%); 441 308 } 442 309 443 - .instance-menu-dropdown.active { 444 - opacity: 1; 445 - visibility: visible; 446 - transform: translateY(0); 310 + .metric-saturation .metric-fill { 311 + background: linear-gradient(90deg, #f5a623 0%, #d68910 100%); 447 312 } 448 313 449 - .instance-menu-item { 450 - display: flex; 451 - align-items: center; 452 - gap: 10px; 453 - padding: 10px 14px; 454 - border: none; 455 - background: none; 456 - cursor: pointer; 457 - font-size: 13px; 458 - color: #1a1a1a; 459 - width: 100%; 460 - text-align: left; 461 - transition: background 0.2s ease; 314 + .metric-error .metric-fill { 315 + background: linear-gradient(90deg, #e74c3c 0%, #c0392b 100%); 462 316 } 463 317 464 - .instance-menu-item:hover { 465 - background: #f9f9f9; 318 + .metric-latency .metric-fill { 319 + background: linear-gradient(90deg, #9b59b6 0%, #8e44ad 100%); 466 320 } 467 321 468 - .instance-menu-item:first-child { 469 - border-radius: 8px 8px 0 0; 322 + .metric-uptime .metric-fill { 323 + background: linear-gradient(90deg, #28a745 0%, #20c997 100%); 470 324 } 471 325 472 - .instance-menu-item:last-child { 473 - border-radius: 0 0 8px 8px; 326 + /* Metric value tooltip */ 327 + .metric-tooltip { 328 + position: absolute; 329 + bottom: -24px; 330 + left: 50%; 331 + transform: translateX(-50%); 332 + background: #333; 333 + color: white; 334 + padding: 4px 8px; 335 + border-radius: 4px; 336 + font-size: 11px; 337 + font-weight: 600; 338 + white-space: nowrap; 339 + opacity: 0; 340 + pointer-events: none; 341 + transition: opacity 0.2s ease; 342 + z-index: 100; 474 343 } 475 344 476 - .instance-menu-item.danger { 477 - color: #ef4444; 345 + .metric-bar:hover + .metric-tooltip, 346 + .metric-tooltip:hover { 347 + opacity: 1; 478 348 } 479 349 480 - .instance-menu-item.danger:hover { 481 - background: #fee2e2; 350 + /* Instance Menu */ 351 + .instance-menu { 352 + flex-shrink: 0; 353 + position: relative; 354 + grid-column: 4; 355 + grid-row: 1; 356 + justify-self: end; 357 + display: flex; 358 + align-items: center; 359 + height: 24px; 482 360 } 483 361 484 - .instance-menu-item-icon { 485 - font-size: 14px; 362 + .menu-btn { 363 + background: none; 364 + border: none; 365 + font-size: 18px; 366 + color: #666; 367 + cursor: pointer; 368 + padding: 4px 8px; 369 + border-radius: 4px; 370 + transition: all 0.2s ease; 486 371 display: flex; 487 372 align-items: center; 488 373 justify-content: center; 489 - width: 16px; 374 + height: 24px; 375 + } 376 + 377 + .menu-btn:hover { 378 + background: #f0f2f5; 379 + color: #333; 490 380 } 491 381 492 - /* Responsive design */ 493 - @media (max-width: 1400px) { 494 - .cluster-header { 495 - flex-wrap: wrap; 496 - padding: 12px 16px; 382 + /* Responsive Design */ 383 + @media (max-width: 768px) { 384 + .instance { 385 + grid-template-columns: auto 1fr auto; 497 386 } 498 387 499 - .metrics-container { 500 - width: 100%; 501 - order: 2; 502 - margin-top: 8px; 388 + .instance-tags { 503 389 } 504 390 505 - .cluster-name { 506 - order: 1; 391 + .metrics { 392 + gap: 12px; 507 393 } 508 394 509 - .menu-container { 510 - order: 3; 511 - margin-left: 0; 512 - margin-top: 8px; 395 + .metric { 396 + min-width: 70px; 513 397 } 514 - } 515 398 516 - @media (max-width: 768px) { 517 - .cluster-header { 518 - flex-wrap: wrap; 519 - padding: 12px 16px; 399 + .metric-tooltip { 400 + bottom: -28px; 520 401 } 402 + } 521 403 522 - .metrics-container { 523 - width: 100%; 524 - order: 2; 525 - margin-top: 8px; 404 + @media (max-width: 480px) { 405 + .header { 406 + flex-direction: column; 526 407 gap: 12px; 408 + align-items: flex-start; 527 409 } 528 410 529 - .metric { 530 - min-width: 100px; 411 + .header-right { 412 + width: 100%; 413 + justify-content: flex-end; 531 414 } 532 415 533 - .header h1 { 534 - font-size: 24px; 416 + .instance { 417 + grid-template-columns: auto 1fr auto; 418 + gap: 8px; 535 419 } 536 420 537 - .instance-item { 538 - flex-wrap: wrap; 421 + .instance-tags { 422 + gap: 4px; 539 423 } 540 424 541 - .metrics-container-small { 542 - width: 100%; 543 - order: 2; 544 - margin-top: 8px; 545 - gap: 12px; 425 + .metrics { 426 + gap: 8px; 546 427 } 547 428 548 - .instance-name-small { 549 - order: 1; 429 + .metric { 430 + min-width: 60px; 550 431 } 551 432 552 - .instance-menu-container { 553 - order: 3; 554 - margin-left: 0; 555 - margin-top: 8px; 433 + .tag { 434 + font-size: 10px; 435 + padding: 3px 6px; 556 436 } 557 437 } 558 438 </style> 559 439 </head> 560 440 <body> 561 - <div class="container"> 562 - <div class="header"> 563 - <h1>Cluster Dashboard</h1> 564 - <p>Monitor your system clusters and instances in real-time</p> 441 + <!-- Header --> 442 + <div class="header"> 443 + <div class="header-left"> 444 + <span class="butterfly-icon">🦋</span> 445 + <h1 class="header-title">MIO Dashboard</h1> 446 + </div> 447 + <div class="header-right"> 448 + <button class="btn btn-primary btn-icon" onclick="showAddInstanceModal()" title="Add Instance"> 449 + 450 + </button> 451 + <div class="dropdown"> 452 + <button class="avatar-btn btn" onclick="toggleProfileMenu()">C</button> 453 + <div class="dropdown-menu" id="profileMenu"> 454 + <button class="dropdown-item">👤 Identity</button> 455 + <button class="dropdown-item">🔑 Secrets</button> 456 + <button class="dropdown-item danger">🚪 Logout</button> 457 + </div> 458 + </div> 565 459 </div> 460 + </div> 566 461 567 - <div class="clusters-list"> 568 - <!-- Cluster 1 --> 569 - <div class="cluster-card"> 570 - <div class="cluster-header" onclick="toggleCluster(this)"> 571 - <div class="expand-icon">▼</div> 572 - <div class="heartbeat healthy">♥</div> 573 - <span class="cluster-name">API Cluster</span> 574 - 575 - <div class="metrics-container"> 576 - <div class="metric"> 577 - <div class="metric-label">Usage</div> 578 - <div class="metric-content"> 579 - <div class="metric-value">62%</div> 580 - <div class="metric-bar"> 581 - <div class="metric-bar-fill usage" style="width: 62%"></div> 582 - </div> 583 - </div> 584 - </div> 585 - 586 - <div class="metric"> 587 - <div class="metric-label">Saturation</div> 588 - <div class="metric-content"> 589 - <div class="metric-value">28%</div> 590 - <div class="metric-bar"> 591 - <div class="metric-bar-fill saturation" style="width: 28%"></div> 592 - </div> 593 - </div> 594 - </div> 595 - 596 - <div class="metric"> 597 - <div class="metric-label">Error Rate</div> 598 - <div class="metric-content"> 599 - <div class="metric-value">0.2%</div> 600 - <div class="metric-bar"> 601 - <div class="metric-bar-fill error" style="width: 2%"></div> 602 - </div> 603 - </div> 604 - </div> 605 - 606 - <div class="metric"> 607 - <div class="metric-label">Latency</div> 608 - <div class="metric-content"> 609 - <div class="metric-value">45ms</div> 610 - <div class="metric-bar"> 611 - <div class="metric-bar-fill latency" style="width: 45%"></div> 612 - </div> 613 - </div> 614 - </div> 462 + <!-- Instances List --> 463 + <div class="instances-container" id="instancesList"> 464 + <!-- Instance 1: Healthy --> 465 + <div class="instance"> 466 + <div class="heartbeat healthy">♥</div> 467 + <div class="instance-name">prod-server-01</div> 468 + <div class="instance-tags"> 469 + <span class="tag" data-label="Type">compute</span> 470 + <span class="tag" data-label="Location">us-east-1</span> 471 + </div> 472 + <div class="instance-menu dropdown"> 473 + <button class="menu-btn" onclick="toggleInstanceMenu(this)">☰</button> 474 + <div class="dropdown-menu"> 475 + <button class="dropdown-item">💻 Terminal</button> 476 + <button class="dropdown-item">💾 Backup</button> 477 + <button class="dropdown-item">⬆️ Upgrade</button> 478 + <button class="dropdown-item">🔄 Reboot</button> 479 + <button class="dropdown-item danger">🗑️ Delete</button> 480 + </div> 481 + </div> 482 + <div class="metrics"> 483 + <div class="metric metric-utilization"> 484 + <div class="metric-bar"> 485 + <div class="metric-fill" style="width: 65%"></div> 615 486 </div> 616 - 617 - <div class="menu-container"> 618 - <button class="menu-button" onclick="toggleMenu(event)">☰</button> 619 - <div class="menu-dropdown"> 620 - <button class="menu-item" onclick="action('backup', 'API Cluster')"> 621 - <span class="menu-item-icon">💾</span> 622 - <span>Trigger Backup</span> 623 - </button> 624 - <button class="menu-item" onclick="action('reboot', 'API Cluster')"> 625 - <span class="menu-item-icon">🔄</span> 626 - <span>Reboot</span> 627 - </button> 628 - <button class="menu-item danger" onclick="action('delete', 'API Cluster')"> 629 - <span class="menu-item-icon">🗑️</span> 630 - <span>Delete</span> 631 - </button> 632 - </div> 487 + <div class="metric-tooltip">Utilization: 65%</div> 488 + </div> 489 + <div class="metric metric-saturation"> 490 + <div class="metric-bar"> 491 + <div class="metric-fill" style="width: 32%"></div> 633 492 </div> 493 + <div class="metric-tooltip">Saturation: 32%</div> 634 494 </div> 635 - 636 - <div class="cluster-content"> 637 - <div class="instances-container"> 638 - <div class="instance-item"> 639 - <span class="instance-name-small">api-instance-1</span> 640 - <div class="metrics-container-small"> 641 - <div class="metric-small"> 642 - <div class="metric-label-small">Usage</div> 643 - <div class="metric-content-small"> 644 - <div class="metric-value-small">58%</div> 645 - <div class="metric-bar-small"> 646 - <div class="metric-bar-fill-small usage" style="width: 58%"></div> 647 - </div> 648 - </div> 649 - </div> 650 - <div class="metric-small"> 651 - <div class="metric-label-small">Saturation</div> 652 - <div class="metric-content-small"> 653 - <div class="metric-value-small">25%</div> 654 - <div class="metric-bar-small"> 655 - <div class="metric-bar-fill-small saturation" style="width: 25%"></div> 656 - </div> 657 - </div> 658 - </div> 659 - <div class="metric-small"> 660 - <div class="metric-label-small">Error Rate</div> 661 - <div class="metric-content-small"> 662 - <div class="metric-value-small">0.1%</div> 663 - <div class="metric-bar-small"> 664 - <div class="metric-bar-fill-small error" style="width: 1%"></div> 665 - </div> 666 - </div> 667 - </div> 668 - <div class="metric-small"> 669 - <div class="metric-label-small">Latency</div> 670 - <div class="metric-content-small"> 671 - <div class="metric-value-small">42ms</div> 672 - <div class="metric-bar-small"> 673 - <div class="metric-bar-fill-small latency" style="width: 42%"></div> 674 - </div> 675 - </div> 676 - </div> 677 - </div> 678 - <div class="instance-menu-container"> 679 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 680 - <div class="instance-menu-dropdown"> 681 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'api-instance-1')"> 682 - <span class="instance-menu-item-icon">💻</span> 683 - <span>Terminal</span> 684 - </button> 685 - <button class="instance-menu-item" onclick="instanceAction('backup', 'api-instance-1')"> 686 - <span class="instance-menu-item-icon">💾</span> 687 - <span>Backup</span> 688 - </button> 689 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'api-instance-1')"> 690 - <span class="instance-menu-item-icon">⬆️</span> 691 - <span>Upgrade</span> 692 - </button> 693 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'api-instance-1')"> 694 - <span class="instance-menu-item-icon">🔄</span> 695 - <span>Reboot</span> 696 - </button> 697 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'api-instance-1')"> 698 - <span class="instance-menu-item-icon">🗑️</span> 699 - <span>Delete</span> 700 - </button> 701 - </div> 702 - </div> 703 - </div> 704 - 705 - <div class="instance-item"> 706 - <span class="instance-name-small">api-instance-2</span> 707 - <div class="metrics-container-small"> 708 - <div class="metric-small"> 709 - <div class="metric-label-small">Usage</div> 710 - <div class="metric-content-small"> 711 - <div class="metric-value-small">65%</div> 712 - <div class="metric-bar-small"> 713 - <div class="metric-bar-fill-small usage" style="width: 65%"></div> 714 - </div> 715 - </div> 716 - </div> 717 - <div class="metric-small"> 718 - <div class="metric-label-small">Saturation</div> 719 - <div class="metric-content-small"> 720 - <div class="metric-value-small">30%</div> 721 - <div class="metric-bar-small"> 722 - <div class="metric-bar-fill-small saturation" style="width: 30%"></div> 723 - </div> 724 - </div> 725 - </div> 726 - <div class="metric-small"> 727 - <div class="metric-label-small">Error Rate</div> 728 - <div class="metric-content-small"> 729 - <div class="metric-value-small">0.3%</div> 730 - <div class="metric-bar-small"> 731 - <div class="metric-bar-fill-small error" style="width: 3%"></div> 732 - </div> 733 - </div> 734 - </div> 735 - <div class="metric-small"> 736 - <div class="metric-label-small">Latency</div> 737 - <div class="metric-content-small"> 738 - <div class="metric-value-small">48ms</div> 739 - <div class="metric-bar-small"> 740 - <div class="metric-bar-fill-small latency" style="width: 48%"></div> 741 - </div> 742 - </div> 743 - </div> 744 - </div> 745 - <div class="instance-menu-container"> 746 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 747 - <div class="instance-menu-dropdown"> 748 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'api-instance-2')"> 749 - <span class="instance-menu-item-icon">💻</span> 750 - <span>Terminal</span> 751 - </button> 752 - <button class="instance-menu-item" onclick="instanceAction('backup', 'api-instance-2')"> 753 - <span class="instance-menu-item-icon">💾</span> 754 - <span>Backup</span> 755 - </button> 756 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'api-instance-2')"> 757 - <span class="instance-menu-item-icon">⬆️</span> 758 - <span>Upgrade</span> 759 - </button> 760 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'api-instance-2')"> 761 - <span class="instance-menu-item-icon">🔄</span> 762 - <span>Reboot</span> 763 - </button> 764 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'api-instance-2')"> 765 - <span class="instance-menu-item-icon">🗑️</span> 766 - <span>Delete</span> 767 - </button> 768 - </div> 769 - </div> 770 - </div> 771 - 772 - <div class="instance-item"> 773 - <span class="instance-name-small">api-instance-3</span> 774 - <div class="metrics-container-small"> 775 - <div class="metric-small"> 776 - <div class="metric-label-small">Usage</div> 777 - <div class="metric-content-small"> 778 - <div class="metric-value-small">63%</div> 779 - <div class="metric-bar-small"> 780 - <div class="metric-bar-fill-small usage" style="width: 63%"></div> 781 - </div> 782 - </div> 783 - </div> 784 - <div class="metric-small"> 785 - <div class="metric-label-small">Saturation</div> 786 - <div class="metric-content-small"> 787 - <div class="metric-value-small">28%</div> 788 - <div class="metric-bar-small"> 789 - <div class="metric-bar-fill-small saturation" style="width: 28%"></div> 790 - </div> 791 - </div> 792 - </div> 793 - <div class="metric-small"> 794 - <div class="metric-label-small">Error Rate</div> 795 - <div class="metric-content-small"> 796 - <div class="metric-value-small">0.2%</div> 797 - <div class="metric-bar-small"> 798 - <div class="metric-bar-fill-small error" style="width: 2%"></div> 799 - </div> 800 - </div> 801 - </div> 802 - <div class="metric-small"> 803 - <div class="metric-label-small">Latency</div> 804 - <div class="metric-content-small"> 805 - <div class="metric-value-small">45ms</div> 806 - <div class="metric-bar-small"> 807 - <div class="metric-bar-fill-small latency" style="width: 45%"></div> 808 - </div> 809 - </div> 810 - </div> 811 - </div> 812 - <div class="instance-menu-container"> 813 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 814 - <div class="instance-menu-dropdown"> 815 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'api-instance-3')"> 816 - <span class="instance-menu-item-icon">💻</span> 817 - <span>Terminal</span> 818 - </button> 819 - <button class="instance-menu-item" onclick="instanceAction('backup', 'api-instance-3')"> 820 - <span class="instance-menu-item-icon">💾</span> 821 - <span>Backup</span> 822 - </button> 823 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'api-instance-3')"> 824 - <span class="instance-menu-item-icon">⬆️</span> 825 - <span>Upgrade</span> 826 - </button> 827 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'api-instance-3')"> 828 - <span class="instance-menu-item-icon">🔄</span> 829 - <span>Reboot</span> 830 - </button> 831 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'api-instance-3')"> 832 - <span class="instance-menu-item-icon">🗑️</span> 833 - <span>Delete</span> 834 - </button> 835 - </div> 836 - </div> 837 - </div> 495 + <div class="metric metric-error"> 496 + <div class="metric-bar"> 497 + <div class="metric-fill" style="width: 2%"></div> 498 + </div> 499 + <div class="metric-tooltip">Error Rate: 0.2%</div> 500 + </div> 501 + <div class="metric metric-latency"> 502 + <div class="metric-bar"> 503 + <div class="metric-fill" style="width: 45%"></div> 504 + </div> 505 + <div class="metric-tooltip">Latency: 120ms</div> 506 + </div> 507 + <div class="metric metric-uptime"> 508 + <div class="metric-bar"> 509 + <div class="metric-fill" style="width: 99.9%"></div> 838 510 </div> 511 + <div class="metric-tooltip">Uptime: 99.9%</div> 839 512 </div> 840 513 </div> 841 - 842 - <!-- Cluster 2 --> 843 - <div class="cluster-card"> 844 - <div class="cluster-header" onclick="toggleCluster(this)"> 845 - <div class="expand-icon">▼</div> 846 - <div class="heartbeat warning">♥</div> 847 - <span class="cluster-name">Database Cluster</span> 848 - 849 - <div class="metrics-container"> 850 - <div class="metric"> 851 - <div class="metric-label">Usage</div> 852 - <div class="metric-content"> 853 - <div class="metric-value">85%</div> 854 - <div class="metric-bar"> 855 - <div class="metric-bar-fill usage" style="width: 85%"></div> 856 - </div> 857 - </div> 858 - </div> 514 + </div> 859 515 860 - <div class="metric"> 861 - <div class="metric-label">Saturation</div> 862 - <div class="metric-content"> 863 - <div class="metric-value">72%</div> 864 - <div class="metric-bar"> 865 - <div class="metric-bar-fill saturation" style="width: 72%"></div> 866 - </div> 867 - </div> 868 - </div> 869 - 870 - <div class="metric"> 871 - <div class="metric-label">Error Rate</div> 872 - <div class="metric-content"> 873 - <div class="metric-value">1.5%</div> 874 - <div class="metric-bar"> 875 - <div class="metric-bar-fill error" style="width: 15%"></div> 876 - </div> 877 - </div> 878 - </div> 879 - 880 - <div class="metric"> 881 - <div class="metric-label">Latency</div> 882 - <div class="metric-content"> 883 - <div class="metric-value">125ms</div> 884 - <div class="metric-bar"> 885 - <div class="metric-bar-fill latency" style="width: 70%"></div> 886 - </div> 887 - </div> 888 - </div> 516 + <!-- Instance 2: Warning --> 517 + <div class="instance"> 518 + <div class="heartbeat warning">���</div> 519 + <div class="instance-name">staging-api-02</div> 520 + <div class="instance-tags"> 521 + <span class="tag" data-label="Type">api</span> 522 + <span class="tag" data-label="Location">eu-west-1</span> 523 + </div> 524 + <div class="instance-menu dropdown"> 525 + <button class="menu-btn" onclick="toggleInstanceMenu(this)">☰</button> 526 + <div class="dropdown-menu"> 527 + <button class="dropdown-item">💻 Terminal</button> 528 + <button class="dropdown-item">💾 Backup</button> 529 + <button class="dropdown-item">⬆️ Upgrade</button> 530 + <button class="dropdown-item">🔄 Reboot</button> 531 + <button class="dropdown-item danger">🗑️ Delete</button> 532 + </div> 533 + </div> 534 + <div class="metrics"> 535 + <div class="metric metric-utilization"> 536 + <div class="metric-bar"> 537 + <div class="metric-fill" style="width: 78%"></div> 889 538 </div> 890 - 891 - <div class="menu-container"> 892 - <button class="menu-button" onclick="toggleMenu(event)">☰</button> 893 - <div class="menu-dropdown"> 894 - <button class="menu-item" onclick="action('backup', 'Database Cluster')"> 895 - <span class="menu-item-icon">💾</span> 896 - <span>Trigger Backup</span> 897 - </button> 898 - <button class="menu-item" onclick="action('reboot', 'Database Cluster')"> 899 - <span class="menu-item-icon">🔄</span> 900 - <span>Reboot</span> 901 - </button> 902 - <button class="menu-item danger" onclick="action('delete', 'Database Cluster')"> 903 - <span class="menu-item-icon">🗑️</span> 904 - <span>Delete</span> 905 - </button> 906 - </div> 539 + <div class="metric-tooltip">Utilization: 78%</div> 540 + </div> 541 + <div class="metric metric-saturation"> 542 + <div class="metric-bar"> 543 + <div class="metric-fill" style="width: 62%"></div> 907 544 </div> 545 + <div class="metric-tooltip">Saturation: 62%</div> 908 546 </div> 909 - 910 - <div class="cluster-content"> 911 - <div class="instances-container"> 912 - <div class="instance-item"> 913 - <span class="instance-name-small">db-primary</span> 914 - <div class="metrics-container-small"> 915 - <div class="metric-small"> 916 - <div class="metric-label-small">Usage</div> 917 - <div class="metric-content-small"> 918 - <div class="metric-value-small">88%</div> 919 - <div class="metric-bar-small"> 920 - <div class="metric-bar-fill-small usage" style="width: 88%"></div> 921 - </div> 922 - </div> 923 - </div> 924 - <div class="metric-small"> 925 - <div class="metric-label-small">Saturation</div> 926 - <div class="metric-content-small"> 927 - <div class="metric-value-small">75%</div> 928 - <div class="metric-bar-small"> 929 - <div class="metric-bar-fill-small saturation" style="width: 75%"></div> 930 - </div> 931 - </div> 932 - </div> 933 - <div class="metric-small"> 934 - <div class="metric-label-small">Error Rate</div> 935 - <div class="metric-content-small"> 936 - <div class="metric-value-small">1.2%</div> 937 - <div class="metric-bar-small"> 938 - <div class="metric-bar-fill-small error" style="width: 12%"></div> 939 - </div> 940 - </div> 941 - </div> 942 - <div class="metric-small"> 943 - <div class="metric-label-small">Latency</div> 944 - <div class="metric-content-small"> 945 - <div class="metric-value-small">120ms</div> 946 - <div class="metric-bar-small"> 947 - <div class="metric-bar-fill-small latency" style="width: 68%"></div> 948 - </div> 949 - </div> 950 - </div> 951 - </div> 952 - <div class="instance-menu-container"> 953 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 954 - <div class="instance-menu-dropdown"> 955 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'db-primary')"> 956 - <span class="instance-menu-item-icon">💻</span> 957 - <span>Terminal</span> 958 - </button> 959 - <button class="instance-menu-item" onclick="instanceAction('backup', 'db-primary')"> 960 - <span class="instance-menu-item-icon">💾</span> 961 - <span>Backup</span> 962 - </button> 963 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'db-primary')"> 964 - <span class="instance-menu-item-icon">⬆️</span> 965 - <span>Upgrade</span> 966 - </button> 967 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'db-primary')"> 968 - <span class="instance-menu-item-icon">🔄</span> 969 - <span>Reboot</span> 970 - </button> 971 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'db-primary')"> 972 - <span class="instance-menu-item-icon">🗑️</span> 973 - <span>Delete</span> 974 - </button> 975 - </div> 976 - </div> 977 - </div> 978 - 979 - <div class="instance-item"> 980 - <span class="instance-name-small">db-replica-1</span> 981 - <div class="metrics-container-small"> 982 - <div class="metric-small"> 983 - <div class="metric-label-small">Usage</div> 984 - <div class="metric-content-small"> 985 - <div class="metric-value-small">82%</div> 986 - <div class="metric-bar-small"> 987 - <div class="metric-bar-fill-small usage" style="width: 82%"></div> 988 - </div> 989 - </div> 990 - </div> 991 - <div class="metric-small"> 992 - <div class="metric-label-small">Saturation</div> 993 - <div class="metric-content-small"> 994 - <div class="metric-value-small">70%</div> 995 - <div class="metric-bar-small"> 996 - <div class="metric-bar-fill-small saturation" style="width: 70%"></div> 997 - </div> 998 - </div> 999 - </div> 1000 - <div class="metric-small"> 1001 - <div class="metric-label-small">Error Rate</div> 1002 - <div class="metric-content-small"> 1003 - <div class="metric-value-small">1.8%</div> 1004 - <div class="metric-bar-small"> 1005 - <div class="metric-bar-fill-small error" style="width: 18%"></div> 1006 - </div> 1007 - </div> 1008 - </div> 1009 - <div class="metric-small"> 1010 - <div class="metric-label-small">Latency</div> 1011 - <div class="metric-content-small"> 1012 - <div class="metric-value-small">130ms</div> 1013 - <div class="metric-bar-small"> 1014 - <div class="metric-bar-fill-small latency" style="width: 72%"></div> 1015 - </div> 1016 - </div> 1017 - </div> 1018 - </div> 1019 - <div class="instance-menu-container"> 1020 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 1021 - <div class="instance-menu-dropdown"> 1022 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'db-replica-1')"> 1023 - <span class="instance-menu-item-icon">💻</span> 1024 - <span>Terminal</span> 1025 - </button> 1026 - <button class="instance-menu-item" onclick="instanceAction('backup', 'db-replica-1')"> 1027 - <span class="instance-menu-item-icon">💾</span> 1028 - <span>Backup</span> 1029 - </button> 1030 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'db-replica-1')"> 1031 - <span class="instance-menu-item-icon">⬆️</span> 1032 - <span>Upgrade</span> 1033 - </button> 1034 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'db-replica-1')"> 1035 - <span class="instance-menu-item-icon">🔄</span> 1036 - <span>Reboot</span> 1037 - </button> 1038 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'db-replica-1')"> 1039 - <span class="instance-menu-item-icon">🗑️</span> 1040 - <span>Delete</span> 1041 - </button> 1042 - </div> 1043 - </div> 1044 - </div> 547 + <div class="metric metric-error"> 548 + <div class="metric-bar"> 549 + <div class="metric-fill" style="width: 5%"></div> 550 + </div> 551 + <div class="metric-tooltip">Error Rate: 0.5%</div> 552 + </div> 553 + <div class="metric metric-latency"> 554 + <div class="metric-bar"> 555 + <div class="metric-fill" style="width: 72%"></div> 556 + </div> 557 + <div class="metric-tooltip">Latency: 245ms</div> 558 + </div> 559 + <div class="metric metric-uptime"> 560 + <div class="metric-bar"> 561 + <div class="metric-fill" style="width: 98.5%"></div> 562 + </div> 563 + <div class="metric-tooltip">Uptime: 98.5%</div> 564 + </div> 565 + </div> 566 + </div> 1045 567 1046 - <div class="instance-item"> 1047 - <span class="instance-name-small">db-replica-2</span> 1048 - <div class="metrics-container-small"> 1049 - <div class="metric-small"> 1050 - <div class="metric-label-small">Usage</div> 1051 - <div class="metric-content-small"> 1052 - <div class="metric-value-small">85%</div> 1053 - <div class="metric-bar-small"> 1054 - <div class="metric-bar-fill-small usage" style="width: 85%"></div> 1055 - </div> 1056 - </div> 1057 - </div> 1058 - <div class="metric-small"> 1059 - <div class="metric-label-small">Saturation</div> 1060 - <div class="metric-content-small"> 1061 - <div class="metric-value-small">72%</div> 1062 - <div class="metric-bar-small"> 1063 - <div class="metric-bar-fill-small saturation" style="width: 72%"></div> 1064 - </div> 1065 - </div> 1066 - </div> 1067 - <div class="metric-small"> 1068 - <div class="metric-label-small">Error Rate</div> 1069 - <div class="metric-content-small"> 1070 - <div class="metric-value-small">1.5%</div> 1071 - <div class="metric-bar-small"> 1072 - <div class="metric-bar-fill-small error" style="width: 15%"></div> 1073 - </div> 1074 - </div> 1075 - </div> 1076 - <div class="metric-small"> 1077 - <div class="metric-label-small">Latency</div> 1078 - <div class="metric-content-small"> 1079 - <div class="metric-value-small">125ms</div> 1080 - <div class="metric-bar-small"> 1081 - <div class="metric-bar-fill-small latency" style="width: 70%"></div> 1082 - </div> 1083 - </div> 1084 - </div> 1085 - </div> 1086 - <div class="instance-menu-container"> 1087 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 1088 - <div class="instance-menu-dropdown"> 1089 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'db-replica-2')"> 1090 - <span class="instance-menu-item-icon">💻</span> 1091 - <span>Terminal</span> 1092 - </button> 1093 - <button class="instance-menu-item" onclick="instanceAction('backup', 'db-replica-2')"> 1094 - <span class="instance-menu-item-icon">💾</span> 1095 - <span>Backup</span> 1096 - </button> 1097 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'db-replica-2')"> 1098 - <span class="instance-menu-item-icon">⬆️</span> 1099 - <span>Upgrade</span> 1100 - </button> 1101 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'db-replica-2')"> 1102 - <span class="instance-menu-item-icon">🔄</span> 1103 - <span>Reboot</span> 1104 - </button> 1105 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'db-replica-2')"> 1106 - <span class="instance-menu-item-icon">🗑️</span> 1107 - <span>Delete</span> 1108 - </button> 1109 - </div> 1110 - </div> 1111 - </div> 568 + <!-- Instance 3: Critical --> 569 + <div class="instance"> 570 + <div class="heartbeat critical">♥</div> 571 + <div class="instance-name">worker-queue-03</div> 572 + <div class="instance-tags"> 573 + <span class="tag" data-label="Type">worker</span> 574 + <span class="tag" data-label="Location">ap-south-1</span> 575 + </div> 576 + <div class="instance-menu dropdown"> 577 + <button class="menu-btn" onclick="toggleInstanceMenu(this)">☰</button> 578 + <div class="dropdown-menu"> 579 + <button class="dropdown-item">💻 Terminal</button> 580 + <button class="dropdown-item">💾 Backup</button> 581 + <button class="dropdown-item">⬆️ Upgrade</button> 582 + <button class="dropdown-item">🔄 Reboot</button> 583 + <button class="dropdown-item danger">🗑️ Delete</button> 584 + </div> 585 + </div> 586 + <div class="metrics"> 587 + <div class="metric metric-utilization"> 588 + <div class="metric-bar"> 589 + <div class="metric-fill" style="width: 92%"></div> 590 + </div> 591 + <div class="metric-tooltip">Utilization: 92%</div> 592 + </div> 593 + <div class="metric metric-saturation"> 594 + <div class="metric-bar"> 595 + <div class="metric-fill" style="width: 88%"></div> 596 + </div> 597 + <div class="metric-tooltip">Saturation: 88%</div> 598 + </div> 599 + <div class="metric metric-error"> 600 + <div class="metric-bar"> 601 + <div class="metric-fill" style="width: 18%"></div> 602 + </div> 603 + <div class="metric-tooltip">Error Rate: 1.8%</div> 604 + </div> 605 + <div class="metric metric-latency"> 606 + <div class="metric-bar"> 607 + <div class="metric-fill" style="width: 95%"></div> 608 + </div> 609 + <div class="metric-tooltip">Latency: 890ms</div> 610 + </div> 611 + <div class="metric metric-uptime"> 612 + <div class="metric-bar"> 613 + <div class="metric-fill" style="width: 85.2%"></div> 1112 614 </div> 615 + <div class="metric-tooltip">Uptime: 85.2%</div> 1113 616 </div> 1114 617 </div> 1115 - 1116 - <!-- Cluster 3 --> 1117 - <div class="cluster-card"> 1118 - <div class="cluster-header" onclick="toggleCluster(this)"> 1119 - <div class="expand-icon">▼</div> 1120 - <div class="heartbeat critical">♥</div> 1121 - <span class="cluster-name">Cache Cluster</span> 1122 - 1123 - <div class="metrics-container"> 1124 - <div class="metric"> 1125 - <div class="metric-label">Usage</div> 1126 - <div class="metric-content"> 1127 - <div class="metric-value">92%</div> 1128 - <div class="metric-bar"> 1129 - <div class="metric-bar-fill usage" style="width: 92%"></div> 1130 - </div> 1131 - </div> 1132 - </div> 1133 - 1134 - <div class="metric"> 1135 - <div class="metric-label">Saturation</div> 1136 - <div class="metric-content"> 1137 - <div class="metric-value">88%</div> 1138 - <div class="metric-bar"> 1139 - <div class="metric-bar-fill saturation" style="width: 88%"></div> 1140 - </div> 1141 - </div> 1142 - </div> 618 + </div> 1143 619 1144 - <div class="metric"> 1145 - <div class="metric-label">Error Rate</div> 1146 - <div class="metric-content"> 1147 - <div class="metric-value">5.8%</div> 1148 - <div class="metric-bar"> 1149 - <div class="metric-bar-fill error" style="width: 58%"></div> 1150 - </div> 1151 - </div> 1152 - </div> 1153 - 1154 - <div class="metric"> 1155 - <div class="metric-label">Latency</div> 1156 - <div class="metric-content"> 1157 - <div class="metric-value">340ms</div> 1158 - <div class="metric-bar"> 1159 - <div class="metric-bar-fill latency" style="width: 95%"></div> 1160 - </div> 1161 - </div> 1162 - </div> 620 + <!-- Instance 4: Healthy --> 621 + <div class="instance"> 622 + <div class="heartbeat healthy">♥</div> 623 + <div class="instance-name">db-primary-01</div> 624 + <div class="instance-tags"> 625 + <span class="tag" data-label="Type">database</span> 626 + <span class="tag" data-label="Location">us-west-2</span> 627 + </div> 628 + <div class="instance-menu dropdown"> 629 + <button class="menu-btn" onclick="toggleInstanceMenu(this)">☰</button> 630 + <div class="dropdown-menu"> 631 + <button class="dropdown-item">💻 Terminal</button> 632 + <button class="dropdown-item">💾 Backup</button> 633 + <button class="dropdown-item">⬆️ Upgrade</button> 634 + <button class="dropdown-item">🔄 Reboot</button> 635 + <button class="dropdown-item danger">🗑️ Delete</button> 636 + </div> 637 + </div> 638 + <div class="metrics"> 639 + <div class="metric metric-utilization"> 640 + <div class="metric-bar"> 641 + <div class="metric-fill" style="width: 54%"></div> 1163 642 </div> 1164 - 1165 - <div class="menu-container"> 1166 - <button class="menu-button" onclick="toggleMenu(event)">☰</button> 1167 - <div class="menu-dropdown"> 1168 - <button class="menu-item" onclick="action('backup', 'Cache Cluster')"> 1169 - <span class="menu-item-icon">💾</span> 1170 - <span>Trigger Backup</span> 1171 - </button> 1172 - <button class="menu-item" onclick="action('reboot', 'Cache Cluster')"> 1173 - <span class="menu-item-icon">🔄</span> 1174 - <span>Reboot</span> 1175 - </button> 1176 - <button class="menu-item danger" onclick="action('delete', 'Cache Cluster')"> 1177 - <span class="menu-item-icon">🗑️</span> 1178 - <span>Delete</span> 1179 - </button> 1180 - </div> 643 + <div class="metric-tooltip">Utilization: 54%</div> 644 + </div> 645 + <div class="metric metric-saturation"> 646 + <div class="metric-bar"> 647 + <div class="metric-fill" style="width: 28%"></div> 1181 648 </div> 649 + <div class="metric-tooltip">Saturation: 28%</div> 1182 650 </div> 1183 - 1184 - <div class="cluster-content"> 1185 - <div class="instances-container"> 1186 - <div class="instance-item"> 1187 - <span class="instance-name-small">cache-1</span> 1188 - <div class="metrics-container-small"> 1189 - <div class="metric-small"> 1190 - <div class="metric-label-small">Usage</div> 1191 - <div class="metric-content-small"> 1192 - <div class="metric-value-small">91%</div> 1193 - <div class="metric-bar-small"> 1194 - <div class="metric-bar-fill-small usage" style="width: 91%"></div> 1195 - </div> 1196 - </div> 1197 - </div> 1198 - <div class="metric-small"> 1199 - <div class="metric-label-small">Saturation</div> 1200 - <div class="metric-content-small"> 1201 - <div class="metric-value-small">86%</div> 1202 - <div class="metric-bar-small"> 1203 - <div class="metric-bar-fill-small saturation" style="width: 86%"></div> 1204 - </div> 1205 - </div> 1206 - </div> 1207 - <div class="metric-small"> 1208 - <div class="metric-label-small">Error Rate</div> 1209 - <div class="metric-content-small"> 1210 - <div class="metric-value-small">5.5%</div> 1211 - <div class="metric-bar-small"> 1212 - <div class="metric-bar-fill-small error" style="width: 55%"></div> 1213 - </div> 1214 - </div> 1215 - </div> 1216 - <div class="metric-small"> 1217 - <div class="metric-label-small">Latency</div> 1218 - <div class="metric-content-small"> 1219 - <div class="metric-value-small">335ms</div> 1220 - <div class="metric-bar-small"> 1221 - <div class="metric-bar-fill-small latency" style="width: 94%"></div> 1222 - </div> 1223 - </div> 1224 - </div> 1225 - </div> 1226 - <div class="instance-menu-container"> 1227 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 1228 - <div class="instance-menu-dropdown"> 1229 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'cache-1')"> 1230 - <span class="instance-menu-item-icon">💻</span> 1231 - <span>Terminal</span> 1232 - </button> 1233 - <button class="instance-menu-item" onclick="instanceAction('backup', 'cache-1')"> 1234 - <span class="instance-menu-item-icon">💾</span> 1235 - <span>Backup</span> 1236 - </button> 1237 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'cache-1')"> 1238 - <span class="instance-menu-item-icon">⬆️</span> 1239 - <span>Upgrade</span> 1240 - </button> 1241 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'cache-1')"> 1242 - <span class="instance-menu-item-icon">🔄</span> 1243 - <span>Reboot</span> 1244 - </button> 1245 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'cache-1')"> 1246 - <span class="instance-menu-item-icon">🗑️</span> 1247 - <span>Delete</span> 1248 - </button> 1249 - </div> 1250 - </div> 1251 - </div> 1252 - 1253 - <div class="instance-item"> 1254 - <span class="instance-name-small">cache-2</span> 1255 - <div class="metrics-container-small"> 1256 - <div class="metric-small"> 1257 - <div class="metric-label-small">Usage</div> 1258 - <div class="metric-content-small"> 1259 - <div class="metric-value-small">93%</div> 1260 - <div class="metric-bar-small"> 1261 - <div class="metric-bar-fill-small usage" style="width: 93%"></div> 1262 - </div> 1263 - </div> 1264 - </div> 1265 - <div class="metric-small"> 1266 - <div class="metric-label-small">Saturation</div> 1267 - <div class="metric-content-small"> 1268 - <div class="metric-value-small">89%</div> 1269 - <div class="metric-bar-small"> 1270 - <div class="metric-bar-fill-small saturation" style="width: 89%"></div> 1271 - </div> 1272 - </div> 1273 - </div> 1274 - <div class="metric-small"> 1275 - <div class="metric-label-small">Error Rate</div> 1276 - <div class="metric-content-small"> 1277 - <div class="metric-value-small">6.2%</div> 1278 - <div class="metric-bar-small"> 1279 - <div class="metric-bar-fill-small error" style="width: 62%"></div> 1280 - </div> 1281 - </div> 1282 - </div> 1283 - <div class="metric-small"> 1284 - <div class="metric-label-small">Latency</div> 1285 - <div class="metric-content-small"> 1286 - <div class="metric-value-small">345ms</div> 1287 - <div class="metric-bar-small"> 1288 - <div class="metric-bar-fill-small latency" style="width: 96%"></div> 1289 - </div> 1290 - </div> 1291 - </div> 1292 - </div> 1293 - <div class="instance-menu-container"> 1294 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 1295 - <div class="instance-menu-dropdown"> 1296 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'cache-2')"> 1297 - <span class="instance-menu-item-icon">💻</span> 1298 - <span>Terminal</span> 1299 - </button> 1300 - <button class="instance-menu-item" onclick="instanceAction('backup', 'cache-2')"> 1301 - <span class="instance-menu-item-icon">💾</span> 1302 - <span>Backup</span> 1303 - </button> 1304 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'cache-2')"> 1305 - <span class="instance-menu-item-icon">⬆️</span> 1306 - <span>Upgrade</span> 1307 - </button> 1308 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'cache-2')"> 1309 - <span class="instance-menu-item-icon">🔄</span> 1310 - <span>Reboot</span> 1311 - </button> 1312 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'cache-2')"> 1313 - <span class="instance-menu-item-icon">🗑️</span> 1314 - <span>Delete</span> 1315 - </button> 1316 - </div> 1317 - </div> 1318 - </div> 1319 - 1320 - <div class="instance-item"> 1321 - <span class="instance-name-small">cache-3</span> 1322 - <div class="metrics-container-small"> 1323 - <div class="metric-small"> 1324 - <div class="metric-label-small">Usage</div> 1325 - <div class="metric-content-small"> 1326 - <div class="metric-value-small">92%</div> 1327 - <div class="metric-bar-small"> 1328 - <div class="metric-bar-fill-small usage" style="width: 92%"></div> 1329 - </div> 1330 - </div> 1331 - </div> 1332 - <div class="metric-small"> 1333 - <div class="metric-label-small">Saturation</div> 1334 - <div class="metric-content-small"> 1335 - <div class="metric-value-small">88%</div> 1336 - <div class="metric-bar-small"> 1337 - <div class="metric-bar-fill-small saturation" style="width: 88%"></div> 1338 - </div> 1339 - </div> 1340 - </div> 1341 - <div class="metric-small"> 1342 - <div class="metric-label-small">Error Rate</div> 1343 - <div class="metric-content-small"> 1344 - <div class="metric-value-small">5.8%</div> 1345 - <div class="metric-bar-small"> 1346 - <div class="metric-bar-fill-small error" style="width: 58%"></div> 1347 - </div> 1348 - </div> 1349 - </div> 1350 - <div class="metric-small"> 1351 - <div class="metric-label-small">Latency</div> 1352 - <div class="metric-content-small"> 1353 - <div class="metric-value-small">340ms</div> 1354 - <div class="metric-bar-small"> 1355 - <div class="metric-bar-fill-small latency" style="width: 95%"></div> 1356 - </div> 1357 - </div> 1358 - </div> 1359 - </div> 1360 - <div class="instance-menu-container"> 1361 - <button class="instance-menu-button" onclick="toggleInstanceMenu(event)">☰</button> 1362 - <div class="instance-menu-dropdown"> 1363 - <button class="instance-menu-item" onclick="instanceAction('terminal', 'cache-3')"> 1364 - <span class="instance-menu-item-icon">💻</span> 1365 - <span>Terminal</span> 1366 - </button> 1367 - <button class="instance-menu-item" onclick="instanceAction('backup', 'cache-3')"> 1368 - <span class="instance-menu-item-icon">💾</span> 1369 - <span>Backup</span> 1370 - </button> 1371 - <button class="instance-menu-item" onclick="instanceAction('upgrade', 'cache-3')"> 1372 - <span class="instance-menu-item-icon">⬆️</span> 1373 - <span>Upgrade</span> 1374 - </button> 1375 - <button class="instance-menu-item" onclick="instanceAction('reboot', 'cache-3')"> 1376 - <span class="instance-menu-item-icon">🔄</span> 1377 - <span>Reboot</span> 1378 - </button> 1379 - <button class="instance-menu-item danger" onclick="instanceAction('delete', 'cache-3')"> 1380 - <span class="instance-menu-item-icon">🗑️</span> 1381 - <span>Delete</span> 1382 - </button> 1383 - </div> 1384 - </div> 1385 - </div> 651 + <div class="metric metric-error"> 652 + <div class="metric-bar"> 653 + <div class="metric-fill" style="width: 1%"></div> 654 + </div> 655 + <div class="metric-tooltip">Error Rate: 0.1%</div> 656 + </div> 657 + <div class="metric metric-latency"> 658 + <div class="metric-bar"> 659 + <div class="metric-fill" style="width: 35%"></div> 660 + </div> 661 + <div class="metric-tooltip">Latency: 85ms</div> 662 + </div> 663 + <div class="metric metric-uptime"> 664 + <div class="metric-bar"> 665 + <div class="metric-fill" style="width: 99.98%"></div> 1386 666 </div> 667 + <div class="metric-tooltip">Uptime: 99.98%</div> 1387 668 </div> 1388 669 </div> 1389 670 </div> 1390 671 </div> 1391 672 1392 673 <script> 1393 - function toggleCluster(header) { 1394 - const card = header.closest('.cluster-card'); 1395 - card.classList.toggle('expanded'); 674 + // Close all dropdowns when clicking outside 675 + document.addEventListener('click', function(event) { 676 + if (!event.target.closest('.dropdown')) { 677 + document.querySelectorAll('.dropdown-menu').forEach(menu => { 678 + menu.classList.remove('active'); 679 + }); 680 + } 681 + }); 682 + 683 + // Toggle profile menu 684 + function toggleProfileMenu() { 685 + const menu = document.getElementById('profileMenu'); 686 + menu.classList.toggle('active'); 1396 687 } 1397 688 1398 - function toggleMenu(event) { 1399 - event.stopPropagation(); 1400 - const button = event.currentTarget; 1401 - const dropdown = button.nextElementSibling; 689 + // Toggle instance menu 690 + function toggleInstanceMenu(button) { 691 + const menu = button.nextElementSibling; 1402 692 1403 693 // Close all other menus 1404 - document.querySelectorAll('.menu-dropdown.active').forEach(menu => { 1405 - if (menu !== dropdown) { 1406 - menu.classList.remove('active'); 1407 - } 694 + document.querySelectorAll('.instance-menu .dropdown-menu').forEach(m => { 695 + if (m !== menu) m.classList.remove('active'); 1408 696 }); 1409 697 1410 - dropdown.classList.toggle('active'); 698 + menu.classList.toggle('active'); 1411 699 } 1412 700 1413 - function toggleInstanceMenu(event) { 1414 - event.stopPropagation(); 1415 - const button = event.currentTarget; 1416 - const dropdown = button.nextElementSibling; 1417 - 1418 - // Close all other instance menus 1419 - document.querySelectorAll('.instance-menu-dropdown.active').forEach(menu => { 1420 - if (menu !== dropdown) { 1421 - menu.classList.remove('active'); 1422 - } 1423 - }); 1424 - 1425 - dropdown.classList.toggle('active'); 701 + // Add instance modal 702 + function showAddInstanceModal() { 703 + alert('Add new instance modal would open here'); 1426 704 } 1427 705 1428 - function action(type, clusterName) { 1429 - const actionNames = { 1430 - 'backup': 'Backup triggered', 1431 - 'reboot': 'Reboot initiated', 1432 - 'delete': 'Delete confirmation' 1433 - }; 1434 - 1435 - alert(`${actionNames[type]} for "${clusterName}"`); 1436 - 1437 - // Close the menu 1438 - document.querySelectorAll('.menu-dropdown').forEach(menu => { 1439 - menu.classList.remove('active'); 1440 - }); 1441 - } 1442 - 1443 - function instanceAction(type, instanceName) { 1444 - const actionNames = { 1445 - 'terminal': 'Terminal opened', 1446 - 'backup': 'Backup started', 1447 - 'upgrade': 'Upgrade initiated', 1448 - 'reboot': 'Reboot initiated', 1449 - 'delete': 'Delete confirmation' 1450 - }; 1451 - 1452 - alert(`${actionNames[type]} for "${instanceName}"`); 1453 - 1454 - // Close the menu 1455 - document.querySelectorAll('.instance-menu-dropdown').forEach(menu => { 1456 - menu.classList.remove('active'); 706 + // Handle instance menu actions 707 + document.querySelectorAll('.instance-menu .dropdown-item').forEach(item => { 708 + item.addEventListener('click', function() { 709 + const action = this.textContent.trim(); 710 + console.log('Instance action:', action); 1457 711 }); 1458 - } 712 + }); 1459 713 1460 - // Close menus when clicking outside 1461 - document.addEventListener('click', () => { 1462 - document.querySelectorAll('.menu-dropdown.active').forEach(menu => { 1463 - menu.classList.remove('active'); 1464 - }); 1465 - document.querySelectorAll('.instance-menu-dropdown.active').forEach(menu => { 1466 - menu.classList.remove('active'); 714 + // Handle profile menu actions 715 + document.querySelectorAll('#profileMenu .dropdown-item').forEach(item => { 716 + item.addEventListener('click', function() { 717 + const action = this.textContent.trim(); 718 + console.log('Profile action:', action); 1467 719 }); 1468 720 }); 1469 721 </script>