termweb-dashboard 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,486 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>termweb-dashboard</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body {
10
+ background: #1e1e1e;
11
+ color: #cccccc;
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
+ font-size: 13px;
14
+ }
15
+ #header {
16
+ height: 36px;
17
+ background: #252526;
18
+ display: flex;
19
+ align-items: center;
20
+ padding: 0 16px;
21
+ border-bottom: 1px solid #3c3c3c;
22
+ }
23
+ #header h1 { font-size: 14px; font-weight: 600; flex: 1; }
24
+ #header .info { font-size: 11px; color: #888; }
25
+
26
+ #dashboard {
27
+ display: grid;
28
+ grid-template-columns: repeat(2, 1fr);
29
+ gap: 16px;
30
+ padding: 16px;
31
+ height: calc(100vh - 36px - 32px);
32
+ overflow: auto;
33
+ }
34
+ .card {
35
+ background: #252526;
36
+ border: 1px solid #3c3c3c;
37
+ border-radius: 6px;
38
+ padding: 16px;
39
+ }
40
+ .card h2 {
41
+ font-size: 12px;
42
+ font-weight: 600;
43
+ color: #569cd6;
44
+ margin-bottom: 12px;
45
+ text-transform: uppercase;
46
+ letter-spacing: 0.5px;
47
+ }
48
+ .card.full-width { grid-column: span 2; }
49
+
50
+ .stat-row {
51
+ display: flex;
52
+ justify-content: space-between;
53
+ padding: 6px 0;
54
+ border-bottom: 1px solid #3c3c3c;
55
+ }
56
+ .stat-row:last-child { border-bottom: none; }
57
+ .stat-label { color: #888; }
58
+ .stat-value { font-weight: 500; }
59
+ .stat-value.high { color: #f14c4c; }
60
+ .stat-value.medium { color: #dcdcaa; }
61
+ .stat-value.low { color: #6a9955; }
62
+
63
+ .progress-bar {
64
+ height: 8px;
65
+ background: #3c3c3c;
66
+ border-radius: 4px;
67
+ overflow: hidden;
68
+ margin-top: 6px;
69
+ }
70
+ .progress-fill {
71
+ height: 100%;
72
+ border-radius: 4px;
73
+ transition: width 0.3s ease;
74
+ }
75
+ .progress-fill.cpu { background: linear-gradient(90deg, #4ec9b0, #569cd6); }
76
+ .progress-fill.mem { background: linear-gradient(90deg, #569cd6, #9cdcfe); }
77
+ .progress-fill.disk { background: linear-gradient(90deg, #dcdcaa, #ce9178); }
78
+
79
+ .chart-container { height: 120px; position: relative; }
80
+
81
+ #process-table {
82
+ width: 100%;
83
+ font-size: 11px;
84
+ }
85
+ #process-table tbody {
86
+ display: block;
87
+ position: relative;
88
+ }
89
+ #process-table tbody tr {
90
+ display: flex;
91
+ position: absolute;
92
+ width: 100%;
93
+ left: 0;
94
+ transition: transform 0.4s ease-out;
95
+ }
96
+ #process-table th, #process-table td {
97
+ text-align: left;
98
+ padding: 4px 8px;
99
+ }
100
+ #process-table thead tr {
101
+ display: flex;
102
+ }
103
+ #process-table th {
104
+ background: #1e1e1e;
105
+ color: #888;
106
+ font-weight: 600;
107
+ }
108
+ #process-table th.sorted {
109
+ color: #569cd6;
110
+ }
111
+ #process-table td {
112
+ border-bottom: 1px solid #2d2d2d;
113
+ }
114
+ /* Column widths for mini table */
115
+ #process-table th:nth-child(1), #process-table td:nth-child(1) { width: 60px; }
116
+ #process-table th:nth-child(2), #process-table td:nth-child(2) { flex: 1; }
117
+ #process-table th:nth-child(3), #process-table td:nth-child(3) { width: 60px; }
118
+ #process-table th:nth-child(4), #process-table td:nth-child(4) { width: 60px; }
119
+ #process-table th:nth-child(5), #process-table td:nth-child(5) { width: 80px; }
120
+ #process-table tbody tr:hover { background: #2a2d2e; }
121
+
122
+ .core-grid {
123
+ display: flex;
124
+ flex-wrap: wrap;
125
+ gap: 4px;
126
+ }
127
+ .core-item {
128
+ text-align: center;
129
+ padding: 2px 6px;
130
+ background: #1e1e1e;
131
+ border-radius: 3px;
132
+ min-width: 32px;
133
+ }
134
+ .core-item .label { font-size: 8px; color: #666; }
135
+ .core-item .value { font-size: 9px; font-weight: 500; }
136
+
137
+ /* Fullscreen views */
138
+ #process-fullscreen, #detail-fullscreen {
139
+ display: none;
140
+ flex-direction: column;
141
+ height: calc(100vh - 36px - 32px);
142
+ padding: 16px;
143
+ }
144
+ .detail-header {
145
+ margin-bottom: 16px;
146
+ }
147
+ .detail-header h2 {
148
+ font-size: 16px;
149
+ color: #569cd6;
150
+ margin: 0;
151
+ }
152
+ .detail-content {
153
+ flex: 1;
154
+ overflow: auto;
155
+ display: flex;
156
+ flex-direction: column;
157
+ }
158
+ .detail-chart {
159
+ height: 200px;
160
+ margin-bottom: 16px;
161
+ }
162
+ .process-header {
163
+ display: flex;
164
+ align-items: center;
165
+ gap: 16px;
166
+ margin-bottom: 12px;
167
+ }
168
+ .process-header h2 {
169
+ font-size: 14px;
170
+ color: #569cd6;
171
+ margin: 0;
172
+ }
173
+ .process-header input {
174
+ flex: 1;
175
+ max-width: 300px;
176
+ padding: 6px 12px;
177
+ background: #1e1e1e;
178
+ border: 1px solid #3c3c3c;
179
+ border-radius: 4px;
180
+ color: #ccc;
181
+ font-size: 13px;
182
+ }
183
+ .process-header input:focus {
184
+ outline: none;
185
+ border-color: #569cd6;
186
+ }
187
+ .process-table-wrap {
188
+ flex: 1;
189
+ overflow: auto;
190
+ }
191
+ .process-table {
192
+ width: 100%;
193
+ font-size: 12px;
194
+ }
195
+ .process-table thead {
196
+ position: sticky;
197
+ top: 0;
198
+ z-index: 1;
199
+ }
200
+ .process-table thead tr {
201
+ display: flex;
202
+ width: 100%;
203
+ }
204
+ .process-table tbody {
205
+ display: block;
206
+ position: relative;
207
+ }
208
+ .process-table tbody tr {
209
+ display: flex;
210
+ position: absolute;
211
+ width: 100%;
212
+ left: 0;
213
+ transition: transform 0.4s ease-out;
214
+ }
215
+ .process-table th, .process-table td {
216
+ padding: 3px 8px;
217
+ text-align: left;
218
+ font-size: 11px;
219
+ }
220
+ .process-table th {
221
+ background: #1e1e1e;
222
+ color: #888;
223
+ font-weight: 600;
224
+ }
225
+ .process-table th.sorted { color: #569cd6; }
226
+ .process-table td {
227
+ border-bottom: 1px solid #2d2d2d;
228
+ }
229
+ /* Column widths */
230
+ .process-table th:nth-child(1), .process-table td:nth-child(1) { width: 70px; flex-shrink: 0; }
231
+ .process-table th:nth-child(2), .process-table td:nth-child(2) { flex: 1; min-width: 150px; }
232
+ .process-table th:nth-child(3), .process-table td:nth-child(3) { width: 70px; flex-shrink: 0; }
233
+ .process-table th:nth-child(4), .process-table td:nth-child(4) { width: 70px; flex-shrink: 0; }
234
+ .process-table th:nth-child(5), .process-table td:nth-child(5) { width: 100px; flex-shrink: 0; }
235
+ .process-table th:nth-child(6), .process-table td:nth-child(6) { width: 70px; flex-shrink: 0; }
236
+ .process-table th:nth-child(7), .process-table td:nth-child(7) { width: 80px; flex-shrink: 0; }
237
+ .process-table tbody {
238
+ display: flex;
239
+ flex-direction: column;
240
+ }
241
+ .process-table tr.selected {
242
+ background: linear-gradient(90deg, rgba(86, 156, 214, 0.25) 0%, rgba(86, 156, 214, 0.1) 100%);
243
+ border-left: 2px solid #569cd6;
244
+ }
245
+ .process-table tr.selected td:first-child {
246
+ padding-left: 6px;
247
+ }
248
+ .process-table tr:hover {
249
+ background: #333;
250
+ }
251
+ .process-table:focus, .process-table *:focus,
252
+ #process-fullscreen:focus, #detail-fullscreen:focus,
253
+ body:focus, [tabindex]:focus {
254
+ outline: none;
255
+ }
256
+
257
+ /* Treemap styles */
258
+ .distribution-chart {
259
+ flex: 1;
260
+ min-height: 150px;
261
+ margin-top: 16px;
262
+ }
263
+ .treemap-label {
264
+ font-size: 12px;
265
+ color: #888;
266
+ margin-bottom: 8px;
267
+ text-transform: uppercase;
268
+ letter-spacing: 0.5px;
269
+ }
270
+ .treemap-2d {
271
+ position: relative;
272
+ width: 100%;
273
+ height: calc(100% - 24px);
274
+ min-height: 120px;
275
+ border-radius: 4px;
276
+ }
277
+ .treemap-cell {
278
+ position: absolute;
279
+ display: flex;
280
+ flex-direction: column;
281
+ justify-content: center;
282
+ align-items: center;
283
+ padding: 4px;
284
+ box-sizing: border-box;
285
+ border: 1px solid rgba(30, 30, 30, 0.3);
286
+ overflow: hidden;
287
+ transition: all 0.3s ease;
288
+ cursor: pointer;
289
+ }
290
+ .treemap-cell:hover {
291
+ filter: brightness(1.1);
292
+ z-index: 10;
293
+ }
294
+ #tooltip {
295
+ position: fixed;
296
+ background: #1e1e1e;
297
+ color: #ccc;
298
+ padding: 6px 10px;
299
+ border-radius: 4px;
300
+ font-size: 12px;
301
+ white-space: nowrap;
302
+ z-index: 9999;
303
+ border: 1px solid #569cd6;
304
+ box-shadow: 0 2px 8px rgba(0,0,0,0.5);
305
+ pointer-events: none;
306
+ display: none;
307
+ }
308
+ .treemap-name, .treemap-value {
309
+ pointer-events: none;
310
+ text-shadow: 0 0 2px rgba(255,255,255,0.5);
311
+ }
312
+ .treemap-name {
313
+ font-size: 11px;
314
+ font-weight: 500;
315
+ color: #1e1e1e;
316
+ white-space: nowrap;
317
+ overflow: hidden;
318
+ text-overflow: ellipsis;
319
+ max-width: 100%;
320
+ }
321
+ .treemap-value {
322
+ font-size: 12px;
323
+ font-weight: 600;
324
+ color: #1e1e1e;
325
+ }
326
+
327
+ /* Larger core items for detail view */
328
+ #detail-cpu-cores .core-item {
329
+ padding: 6px 12px;
330
+ min-width: 48px;
331
+ }
332
+ #detail-cpu-cores .core-item .label {
333
+ font-size: 10px;
334
+ }
335
+ #detail-cpu-cores .core-item .value {
336
+ font-size: 14px;
337
+ font-weight: 600;
338
+ }
339
+
340
+ /* Bottom hints bar */
341
+ #hints {
342
+ height: 32px;
343
+ background: #252526;
344
+ border-top: 1px solid #3c3c3c;
345
+ display: flex;
346
+ align-items: center;
347
+ justify-content: center;
348
+ gap: 24px;
349
+ font-size: 11px;
350
+ color: #888;
351
+ }
352
+ #hints span {
353
+ display: flex;
354
+ align-items: center;
355
+ gap: 4px;
356
+ }
357
+
358
+ /* Loading spinner */
359
+ .spinner {
360
+ display: flex;
361
+ align-items: center;
362
+ justify-content: center;
363
+ padding: 24px;
364
+ color: #888;
365
+ font-size: 13px;
366
+ }
367
+ .spinner::before {
368
+ content: '';
369
+ width: 16px;
370
+ height: 16px;
371
+ border: 2px solid #3c3c3c;
372
+ border-top-color: #569cd6;
373
+ border-radius: 50%;
374
+ margin-right: 8px;
375
+ animation: spin 0.8s linear infinite;
376
+ }
377
+ @keyframes spin {
378
+ to { transform: rotate(360deg); }
379
+ }
380
+ @keyframes row-flash {
381
+ 0% { background: rgba(60, 60, 60, 0.6); }
382
+ 100% { background: transparent; }
383
+ }
384
+ .row-new {
385
+ animation: row-flash 0.6s ease-out;
386
+ }
387
+ /* Disk path breadcrumb */
388
+ .disk-path {
389
+ display: flex;
390
+ align-items: center;
391
+ flex-wrap: wrap;
392
+ gap: 4px;
393
+ font-size: 13px;
394
+ margin-bottom: 12px;
395
+ padding: 8px 12px;
396
+ background: #1e1e1e;
397
+ border-radius: 4px;
398
+ overflow-x: auto;
399
+ }
400
+ .path-item {
401
+ color: #569cd6;
402
+ cursor: pointer;
403
+ padding: 2px 6px;
404
+ border-radius: 3px;
405
+ }
406
+ .path-item:hover {
407
+ background: #333;
408
+ }
409
+ </style>
410
+ </head>
411
+ <body tabindex="0" autofocus>
412
+ <div id="header">
413
+ <h1>System Dashboard</h1>
414
+ <span class="info" id="system-info">Loading...</span>
415
+ </div>
416
+
417
+ <div id="main-dashboard">
418
+ <div id="dashboard">
419
+ <!-- CPU Card -->
420
+ <div class="card" id="cpu-card" style="cursor: pointer;">
421
+ <h2>CPU (click to expand)</h2>
422
+ <div id="cpu-info"></div>
423
+ <div class="chart-container">
424
+ <canvas id="cpu-chart"></canvas>
425
+ </div>
426
+ <div class="progress-bar">
427
+ <div class="progress-fill cpu" id="cpu-bar" style="width: 0%"></div>
428
+ </div>
429
+ <div id="cpu-cores" class="core-grid" style="margin-top: 12px;"></div>
430
+ </div>
431
+
432
+ <!-- Memory Card -->
433
+ <div class="card" id="memory-card" style="cursor: pointer;">
434
+ <h2>Memory (click to expand)</h2>
435
+ <div id="mem-info"></div>
436
+ <div class="chart-container">
437
+ <canvas id="mem-chart"></canvas>
438
+ </div>
439
+ <div class="progress-bar">
440
+ <div class="progress-fill mem" id="mem-bar" style="width: 0%"></div>
441
+ </div>
442
+ </div>
443
+
444
+ <!-- Network Card -->
445
+ <div class="card" id="network-card" style="cursor: pointer;">
446
+ <h2>Network (click to expand)</h2>
447
+ <div class="chart-container">
448
+ <canvas id="net-chart"></canvas>
449
+ </div>
450
+ <div id="net-info"></div>
451
+ </div>
452
+
453
+ <!-- Disk Card -->
454
+ <div class="card" id="disk-card" style="cursor: pointer;">
455
+ <h2>Disk (click to expand)</h2>
456
+ <div id="disk-info"></div>
457
+ </div>
458
+
459
+ <!-- Processes Card -->
460
+ <div class="card full-width" id="processes" style="cursor: pointer;">
461
+ <h2>Top Processes (click to expand)</h2>
462
+ <table id="process-table">
463
+ <thead>
464
+ <tr>
465
+ <th>PID</th>
466
+ <th>Name</th>
467
+ <th class="sorted">CPU % ▼</th>
468
+ <th>MEM %</th>
469
+ <th>PORT</th>
470
+ </tr>
471
+ </thead>
472
+ <tbody id="process-tbody"></tbody>
473
+ </table>
474
+ </div>
475
+ </div>
476
+ </div>
477
+
478
+ <div id="process-fullscreen" tabindex="-1"></div>
479
+ <div id="detail-fullscreen" tabindex="-1"></div>
480
+
481
+ <div id="hints"></div>
482
+ <div id="tooltip"></div>
483
+
484
+ <script src="app.bundle.js"></script>
485
+ </body>
486
+ </html>