vrvrv commited on
Commit
f63d432
·
verified ·
1 Parent(s): 2a9fa8b

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +712 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Monitoring Dashboard
3
- emoji: 📚
4
- colorFrom: red
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: monitoring-dashboard
3
+ emoji: 🐳
4
+ colorFrom: pink
5
+ colorTo: green
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,712 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>Advanced Monitoring Dashboard</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .risk-level-1 {
11
+ background-color: #10B981;
12
+ }
13
+ .risk-level-2 {
14
+ background-color: #F59E0B;
15
+ }
16
+ .risk-level-3 {
17
+ background-color: #EF4444;
18
+ }
19
+ .slide-down {
20
+ max-height: 0;
21
+ overflow: hidden;
22
+ transition: max-height 0.3s ease-out;
23
+ }
24
+ .slide-down.active {
25
+ max-height: 500px;
26
+ transition: max-height 0.5s ease-in;
27
+ }
28
+ .spinner {
29
+ animation: spin 1s linear infinite;
30
+ }
31
+ @keyframes spin {
32
+ 0% { transform: rotate(0deg); }
33
+ 100% { transform: rotate(360deg); }
34
+ }
35
+ .square-details {
36
+ background-color: #f9fafb;
37
+ border-left: 4px solid #3b82f6;
38
+ }
39
+ </style>
40
+ </head>
41
+ <body class="bg-gray-100">
42
+ <div class="container mx-auto px-4 py-8">
43
+ <div class="flex justify-between items-center mb-6">
44
+ <h1 class="text-3xl font-bold text-gray-800">Advanced Monitoring Dashboard</h1>
45
+ <div class="flex space-x-3">
46
+ <button id="expandAllBtn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center">
47
+ <i class="fas fa-expand mr-2"></i> Expand All
48
+ </button>
49
+ <button id="exportBtn" class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg flex items-center">
50
+ <i class="fas fa-file-export mr-2"></i> Export
51
+ </button>
52
+ <button id="rerunBtn" class="bg-purple-500 hover:bg-purple-600 text-white px-4 py-2 rounded-lg flex items-center">
53
+ <i class="fas fa-sync-alt mr-2"></i> Rerun
54
+ </button>
55
+ <button id="addBtn" class="bg-indigo-500 hover:bg-indigo-600 text-white px-4 py-2 rounded-lg flex items-center">
56
+ <i class="fas fa-plus mr-2"></i> Add
57
+ </button>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="bg-white rounded-xl shadow-md overflow-hidden">
62
+ <div class="overflow-x-auto">
63
+ <table class="min-w-full divide-y divide-gray-200">
64
+ <thead class="bg-gray-50">
65
+ <tr>
66
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
67
+ <input type="checkbox" id="selectAll" class="rounded text-blue-500">
68
+ </th>
69
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
70
+ SQR MID
71
+ </th>
72
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
73
+ Risk Level
74
+ </th>
75
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
76
+ Recent Message
77
+ </th>
78
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
79
+ Report
80
+ </th>
81
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
82
+ Last Updated
83
+ </th>
84
+ <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
85
+ Actions
86
+ </th>
87
+ </tr>
88
+ </thead>
89
+ <tbody class="bg-white divide-y divide-gray-200" id="monitoringTableBody">
90
+ <!-- Rows will be populated by JavaScript -->
91
+ </tbody>
92
+ </table>
93
+ </div>
94
+ </div>
95
+ </div>
96
+
97
+ <!-- Add Monitoring Modal -->
98
+ <div id="addModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden">
99
+ <div class="bg-white rounded-xl p-6 w-full max-w-md">
100
+ <div class="flex justify-between items-center mb-4">
101
+ <h2 class="text-xl font-bold text-gray-800">Add New Monitoring</h2>
102
+ <button id="closeAddModal" class="text-gray-500 hover:text-gray-700">
103
+ <i class="fas fa-times"></i>
104
+ </button>
105
+ </div>
106
+ <div class="mb-4">
107
+ <label for="sqrMidInput" class="block text-sm font-medium text-gray-700 mb-1">SQR MID</label>
108
+ <input type="text" id="sqrMidInput" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500">
109
+ </div>
110
+ <div id="previewSection" class="hidden mb-4 p-4 bg-gray-50 rounded-lg">
111
+ <div class="flex items-center mb-3">
112
+ <div class="w-16 h-16 bg-gray-200 rounded-lg mr-3 overflow-hidden">
113
+ <img id="previewImage" src="" alt="Preview" class="w-full h-full object-cover">
114
+ </div>
115
+ <div>
116
+ <h3 id="previewName" class="font-medium text-gray-800"></h3>
117
+ <p id="previewDesc" class="text-sm text-gray-600"></p>
118
+ </div>
119
+ </div>
120
+ <div class="text-sm">
121
+ <p class="font-medium text-gray-700 mb-1">Recent Message:</p>
122
+ <p id="previewMessage" class="text-gray-600"></p>
123
+ </div>
124
+ </div>
125
+ <div class="flex justify-end space-x-3">
126
+ <button id="cancelAddBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
127
+ Close
128
+ </button>
129
+ <button id="confirmAddBtn" class="px-4 py-2 bg-indigo-500 text-white rounded-md hover:bg-indigo-600">
130
+ Add & Monitor
131
+ </button>
132
+ </div>
133
+ </div>
134
+ </div>
135
+
136
+ <!-- Config Modal -->
137
+ <div id="configModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden">
138
+ <div class="bg-white rounded-xl p-6 w-full max-w-md">
139
+ <div class="flex justify-between items-center mb-4">
140
+ <h2 class="text-xl font-bold text-gray-800">Edit Monitoring Config</h2>
141
+ <button id="closeConfigModal" class="text-gray-500 hover:text-gray-700">
142
+ <i class="fas fa-times"></i>
143
+ </button>
144
+ </div>
145
+ <div class="mb-4">
146
+ <label class="block text-sm font-medium text-gray-700 mb-1">Monitoring Frequency</label>
147
+ <select id="monitoringInterval" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500">
148
+ <option value="1">1 hour</option>
149
+ <option value="2">2 hours</option>
150
+ <option value="3">3 hours</option>
151
+ <option value="4">4 hours</option>
152
+ <option value="6">6 hours</option>
153
+ <option value="8">8 hours</option>
154
+ <option value="12">12 hours</option>
155
+ <option value="24">24 hours</option>
156
+ </select>
157
+ </div>
158
+ <div class="mb-4">
159
+ <label class="block text-sm font-medium text-gray-700 mb-1">Recent Messages Count</label>
160
+ <select id="messageCount" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500">
161
+ <option value="10">10 messages</option>
162
+ <option value="20">20 messages</option>
163
+ <option value="30">30 messages</option>
164
+ <option value="40">40 messages</option>
165
+ <option value="50">50 messages</option>
166
+ </select>
167
+ </div>
168
+ <div class="flex justify-end space-x-3">
169
+ <button id="cancelConfigBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
170
+ Cancel
171
+ </button>
172
+ <button id="saveConfigBtn" class="px-4 py-2 bg-indigo-500 text-white rounded-md hover:bg-indigo-600">
173
+ Save Changes
174
+ </button>
175
+ </div>
176
+ </div>
177
+ </div>
178
+
179
+ <script>
180
+ // Enhanced sample data with square details
181
+ const monitoringData = [
182
+ {
183
+ sqr_mid: "MID-1001",
184
+ name: "Payment Gateway",
185
+ description: "Main payment processing service",
186
+ image: "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
187
+ risk_level: 1,
188
+ recent_messages: [
189
+ "Transaction processed successfully",
190
+ "No errors detected in last scan",
191
+ "System performance optimal"
192
+ ],
193
+ report: "All systems operational. No issues detected in the last 24 hours.",
194
+ last_updated: "2023-05-15 09:23:45",
195
+ status: "ready",
196
+ config: {
197
+ interval: 1,
198
+ message_count: 10
199
+ }
200
+ },
201
+ {
202
+ sqr_mid: "MID-1002",
203
+ name: "Inventory Service",
204
+ description: "Product inventory management",
205
+ image: "https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
206
+ risk_level: 2,
207
+ recent_messages: [
208
+ "Warning: Low stock detected for SKU-4567",
209
+ "Synchronization with warehouse delayed by 15 minutes",
210
+ "Database backup completed"
211
+ ],
212
+ report: "Minor issues detected. Low stock warnings for 3 products. Synchronization delays.",
213
+ last_updated: "2023-05-15 08:45:12",
214
+ status: "ready",
215
+ config: {
216
+ interval: 2,
217
+ message_count: 20
218
+ }
219
+ },
220
+ {
221
+ sqr_mid: "MID-1003",
222
+ name: "Customer API",
223
+ description: "Customer data access endpoint",
224
+ image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
225
+ risk_level: 3,
226
+ recent_messages: [
227
+ "ERROR: Authentication failure rate at 12%",
228
+ "Response times exceeding SLA by 300ms",
229
+ "Emergency maintenance scheduled"
230
+ ],
231
+ report: "Critical issues detected. High failure rate on authentication. Performance degraded.",
232
+ last_updated: "2023-05-15 07:30:18",
233
+ status: "ready",
234
+ config: {
235
+ interval: 4,
236
+ message_count: 30
237
+ }
238
+ },
239
+ {
240
+ sqr_mid: "MID-1004",
241
+ name: "Order Processing",
242
+ description: "Order fulfillment pipeline",
243
+ image: "https://images.unsplash.com/photo-1556742044-3c52d6e88c62?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
244
+ risk_level: 2,
245
+ recent_messages: [
246
+ "Warning: Processing queue backlog of 125 orders",
247
+ "Shipping API connectivity issues resolved",
248
+ "Daily report generated"
249
+ ],
250
+ report: "Moderate issues. Order backlog detected. Shipping API had temporary outage.",
251
+ last_updated: "2023-05-15 10:15:33",
252
+ status: "ready",
253
+ config: {
254
+ interval: 8,
255
+ message_count: 10
256
+ }
257
+ }
258
+ ];
259
+
260
+ // DOM elements
261
+ const tableBody = document.getElementById('monitoringTableBody');
262
+ const addModal = document.getElementById('addModal');
263
+ const configModal = document.getElementById('configModal');
264
+ const expandAllBtn = document.getElementById('expandAllBtn');
265
+ const exportBtn = document.getElementById('exportBtn');
266
+ const rerunBtn = document.getElementById('rerunBtn');
267
+ const addBtn = document.getElementById('addBtn');
268
+ const selectAll = document.getElementById('selectAll');
269
+ const sqrMidInput = document.getElementById('sqrMidInput');
270
+ const previewSection = document.getElementById('previewSection');
271
+ const confirmAddBtn = document.getElementById('confirmAddBtn');
272
+ const cancelAddBtn = document.getElementById('cancelAddBtn');
273
+ const closeAddModal = document.getElementById('closeAddModal');
274
+ const closeConfigModal = document.getElementById('closeConfigModal');
275
+ const cancelConfigBtn = document.getElementById('cancelConfigBtn');
276
+ const saveConfigBtn = document.getElementById('saveConfigBtn');
277
+
278
+ // Current config being edited
279
+ let currentConfigItem = null;
280
+
281
+ // Initialize the table with enhanced square details
282
+ function renderTable() {
283
+ tableBody.innerHTML = '';
284
+ monitoringData.forEach(item => {
285
+ const row = document.createElement('tr');
286
+ row.className = 'hover:bg-gray-50';
287
+ row.dataset.sqrMid = item.sqr_mid;
288
+
289
+ // Checkbox
290
+ const checkboxCell = document.createElement('td');
291
+ checkboxCell.className = 'px-6 py-4 whitespace-nowrap';
292
+ const checkbox = document.createElement('input');
293
+ checkbox.type = 'checkbox';
294
+ checkbox.className = 'row-checkbox rounded text-blue-500';
295
+ checkboxCell.appendChild(checkbox);
296
+ row.appendChild(checkboxCell);
297
+
298
+ // SQR MID
299
+ const sqrMidCell = document.createElement('td');
300
+ sqrMidCell.className = 'px-6 py-4 whitespace-nowrap';
301
+ sqrMidCell.innerHTML = `<div class="text-sm font-medium text-gray-900">${item.sqr_mid}</div>`;
302
+ row.appendChild(sqrMidCell);
303
+
304
+ // Risk Level
305
+ const riskCell = document.createElement('td');
306
+ riskCell.className = 'px-6 py-4 whitespace-nowrap';
307
+ riskCell.innerHTML = `
308
+ <div class="flex items-center">
309
+ <div class="h-4 w-4 rounded-full risk-level-${item.risk_level} mr-2"></div>
310
+ <span class="text-sm font-medium">Level ${item.risk_level}</span>
311
+ </div>
312
+ `;
313
+ row.appendChild(riskCell);
314
+
315
+ // Recent Messages
316
+ const messagesCell = document.createElement('td');
317
+ messagesCell.className = 'px-6 py-4 whitespace-nowrap';
318
+ messagesCell.innerHTML = `
319
+ <div class="flex items-center">
320
+ <div class="text-sm text-gray-500 max-w-xs truncate">${item.recent_messages[0]}</div>
321
+ <button class="ml-2 text-gray-400 hover:text-gray-600 message-toggle">
322
+ <i class="fas fa-chevron-down"></i>
323
+ </button>
324
+ </div>
325
+ <div class="slide-down mt-2">
326
+ <ul class="text-sm text-gray-500 list-disc pl-5">
327
+ ${item.recent_messages.map(msg => `<li class="mb-1">${msg}</li>`).join('')}
328
+ </ul>
329
+ </div>
330
+ `;
331
+ row.appendChild(messagesCell);
332
+
333
+ // Report
334
+ const reportCell = document.createElement('td');
335
+ reportCell.className = 'px-6 py-4 whitespace-nowrap';
336
+ reportCell.innerHTML = `
337
+ <div class="flex items-center">
338
+ <div class="text-sm text-gray-500 max-w-xs truncate">${item.report.substring(0, 50)}...</div>
339
+ <button class="ml-2 text-gray-400 hover:text-gray-600 report-toggle">
340
+ <i class="fas fa-chevron-down"></i>
341
+ </button>
342
+ </div>
343
+ <div class="slide-down mt-2">
344
+ <div class="text-sm text-gray-500">${item.report}</div>
345
+ </div>
346
+ `;
347
+ row.appendChild(reportCell);
348
+
349
+ // Last Updated
350
+ const updatedCell = document.createElement('td');
351
+ updatedCell.className = 'px-6 py-4 whitespace-nowrap';
352
+ updatedCell.innerHTML = `<div class="text-sm text-gray-500">${item.last_updated}</div>`;
353
+ row.appendChild(updatedCell);
354
+
355
+ // Actions
356
+ const actionsCell = document.createElement('td');
357
+ actionsCell.className = 'px-6 py-4 whitespace-nowrap text-sm font-medium';
358
+ actionsCell.innerHTML = `
359
+ <div class="flex items-center space-x-2">
360
+ <span class="status-badge inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
361
+ item.status === 'ready' ? 'bg-green-100 text-green-800' : 'bg-yellow-100 text-yellow-800'
362
+ }">
363
+ ${item.status === 'rerun' ? '<i class="fas fa-sync-alt spinner mr-1"></i>' : ''}
364
+ ${item.status}
365
+ </span>
366
+ <button class="text-indigo-600 hover:text-indigo-900 config-btn">
367
+ <i class="fas fa-cog"></i>
368
+ </button>
369
+ <button class="text-red-600 hover:text-red-900 delete-btn">
370
+ <i class="fas fa-trash"></i>
371
+ </button>
372
+ </div>
373
+ `;
374
+ row.appendChild(actionsCell);
375
+
376
+ // Square Details Row (initially hidden)
377
+ const detailsRow = document.createElement('tr');
378
+ detailsRow.className = 'square-details hidden';
379
+ detailsRow.dataset.sqrMid = item.sqr_mid;
380
+ detailsRow.innerHTML = `
381
+ <td colspan="8" class="px-6 py-4">
382
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4">
383
+ <div class="col-span-1">
384
+ <h3 class="font-medium text-gray-800 mb-1">Square Details</h3>
385
+ <p class="text-sm text-gray-600 mb-2">${item.description}</p>
386
+ <img src="${item.image}" alt="${item.name}" class="w-full h-32 object-cover rounded-lg">
387
+ </div>
388
+ <div class="col-span-2">
389
+ <h3 class="font-medium text-gray-800 mb-1">Recent Messages</h3>
390
+ <ul class="text-sm text-gray-500 list-disc pl-5">
391
+ ${item.recent_messages.map(msg => `<li class="mb-1">${msg}</li>`).join('')}
392
+ </ul>
393
+ <h3 class="font-medium text-gray-800 mt-3 mb-1">Full Report</h3>
394
+ <p class="text-sm text-gray-500">${item.report}</p>
395
+ </div>
396
+ </div>
397
+ </td>
398
+ `;
399
+
400
+ // Add click handler to show square details when clicking the SQR MID
401
+ sqrMidCell.addEventListener('click', function(e) {
402
+ if (e.target.tagName !== 'INPUT') { // Don't trigger when clicking checkbox
403
+ detailsRow.classList.toggle('hidden');
404
+ }
405
+ });
406
+
407
+ tableBody.appendChild(row);
408
+ tableBody.appendChild(detailsRow);
409
+ });
410
+
411
+ // Add event listeners to all toggle buttons
412
+ document.querySelectorAll('.message-toggle').forEach(btn => {
413
+ btn.addEventListener('click', function() {
414
+ const slideDown = this.closest('td').querySelector('.slide-down');
415
+ slideDown.classList.toggle('active');
416
+ const icon = this.querySelector('i');
417
+ if (slideDown.classList.contains('active')) {
418
+ icon.classList.replace('fa-chevron-down', 'fa-chevron-up');
419
+ } else {
420
+ icon.classList.replace('fa-chevron-up', 'fa-chevron-down');
421
+ }
422
+ });
423
+ });
424
+
425
+ document.querySelectorAll('.report-toggle').forEach(btn => {
426
+ btn.addEventListener('click', function() {
427
+ const slideDown = this.closest('td').querySelector('.slide-down');
428
+ slideDown.classList.toggle('active');
429
+ const icon = this.querySelector('i');
430
+ if (slideDown.classList.contains('active')) {
431
+ icon.classList.replace('fa-chevron-down', 'fa-chevron-up');
432
+ } else {
433
+ icon.classList.replace('fa-chevron-up', 'fa-chevron-down');
434
+ }
435
+ });
436
+ });
437
+
438
+ // Add event listeners to config buttons
439
+ document.querySelectorAll('.config-btn').forEach(btn => {
440
+ btn.addEventListener('click', function() {
441
+ const row = this.closest('tr');
442
+ const sqrMid = row.dataset.sqrMid;
443
+ const item = monitoringData.find(item => item.sqr_mid === sqrMid);
444
+ currentConfigItem = item;
445
+
446
+ // Set current values in modal
447
+ document.getElementById('monitoringInterval').value = item.config.interval;
448
+ document.getElementById('messageCount').value = item.config.message_count;
449
+
450
+ configModal.classList.remove('hidden');
451
+ });
452
+ });
453
+
454
+ // Add event listeners to delete buttons
455
+ document.querySelectorAll('.delete-btn').forEach(btn => {
456
+ btn.addEventListener('click', function() {
457
+ const row = this.closest('tr');
458
+ const sqrMid = row.dataset.sqrMid;
459
+ if (confirm(`Are you sure you want to delete monitoring for ${sqrMid}?`)) {
460
+ const index = monitoringData.findIndex(item => item.sqr_mid === sqrMid);
461
+ if (index !== -1) {
462
+ monitoringData.splice(index, 1);
463
+ renderTable();
464
+ }
465
+ }
466
+ });
467
+ });
468
+ }
469
+
470
+ // Event listeners
471
+ addBtn.addEventListener('click', () => {
472
+ addModal.classList.remove('hidden');
473
+ sqrMidInput.focus();
474
+ });
475
+
476
+ closeAddModal.addEventListener('click', () => {
477
+ addModal.classList.add('hidden');
478
+ previewSection.classList.add('hidden');
479
+ sqrMidInput.value = '';
480
+ });
481
+
482
+ cancelAddBtn.addEventListener('click', () => {
483
+ addModal.classList.add('hidden');
484
+ previewSection.classList.add('hidden');
485
+ sqrMidInput.value = '';
486
+ });
487
+
488
+ closeConfigModal.addEventListener('click', () => {
489
+ configModal.classList.add('hidden');
490
+ });
491
+
492
+ cancelConfigBtn.addEventListener('click', () => {
493
+ configModal.classList.add('hidden');
494
+ });
495
+
496
+ saveConfigBtn.addEventListener('click', () => {
497
+ if (currentConfigItem) {
498
+ currentConfigItem.config.interval = parseInt(document.getElementById('monitoringInterval').value);
499
+ currentConfigItem.config.message_count = parseInt(document.getElementById('messageCount').value);
500
+ renderTable();
501
+ configModal.classList.add('hidden');
502
+ alert('Configuration saved successfully!');
503
+ }
504
+ });
505
+
506
+ expandAllBtn.addEventListener('click', () => {
507
+ const allSlideDowns = document.querySelectorAll('.slide-down');
508
+ const allMessageToggles = document.querySelectorAll('.message-toggle i');
509
+ const allReportToggles = document.querySelectorAll('.report-toggle i');
510
+
511
+ const anyExpanded = Array.from(allSlideDowns).some(el => el.classList.contains('active'));
512
+
513
+ allSlideDowns.forEach(el => {
514
+ if (anyExpanded) {
515
+ el.classList.remove('active');
516
+ } else {
517
+ el.classList.add('active');
518
+ }
519
+ });
520
+
521
+ allMessageToggles.forEach(icon => {
522
+ if (anyExpanded) {
523
+ icon.classList.replace('fa-chevron-up', 'fa-chevron-down');
524
+ } else {
525
+ icon.classList.replace('fa-chevron-down', 'fa-chevron-up');
526
+ }
527
+ });
528
+
529
+ allReportToggles.forEach(icon => {
530
+ if (anyExpanded) {
531
+ icon.classList.replace('fa-chevron-up', 'fa-chevron-down');
532
+ } else {
533
+ icon.classList.replace('fa-chevron-down', 'fa-chevron-up');
534
+ }
535
+ });
536
+ });
537
+
538
+ exportBtn.addEventListener('click', () => {
539
+ const selectedRows = Array.from(document.querySelectorAll('.row-checkbox:checked')).map(checkbox => {
540
+ return checkbox.closest('tr').dataset.sqrMid;
541
+ });
542
+
543
+ if (selectedRows.length === 0) {
544
+ alert('Please select at least one row to export.');
545
+ return;
546
+ }
547
+
548
+ const dataToExport = monitoringData.filter(item => selectedRows.includes(item.sqr_mid));
549
+
550
+ // In a real app, this would generate an actual Excel file
551
+ console.log('Exporting data:', dataToExport);
552
+ alert(`Preparing export for ${selectedRows.length} selected items.`);
553
+ });
554
+
555
+ rerunBtn.addEventListener('click', () => {
556
+ const selectedRows = Array.from(document.querySelectorAll('.row-checkbox:checked')).map(checkbox => {
557
+ return checkbox.closest('tr').dataset.sqrMid;
558
+ });
559
+
560
+ if (selectedRows.length === 0) {
561
+ alert('Please select at least one row to rerun.');
562
+ return;
563
+ }
564
+
565
+ // Update status to rerun and show loading spinner
566
+ monitoringData.forEach(item => {
567
+ if (selectedRows.includes(item.sqr_mid)) {
568
+ item.status = 'rerun';
569
+ }
570
+ });
571
+
572
+ renderTable();
573
+
574
+ // Simulate server response after 3 seconds
575
+ setTimeout(() => {
576
+ monitoringData.forEach(item => {
577
+ if (selectedRows.includes(item.sqr_mid)) {
578
+ item.status = 'ready';
579
+ // Simulate updated data
580
+ item.last_updated = new Date().toISOString().replace('T', ' ').substring(0, 19);
581
+
582
+ // Randomly change risk level for demo purposes
583
+ if (Math.random() > 0.7) {
584
+ item.risk_level = Math.floor(Math.random() * 3) + 1;
585
+ }
586
+
587
+ // Add a new recent message
588
+ const messages = [
589
+ "Rerun completed successfully",
590
+ "New data processed",
591
+ "System check completed",
592
+ "Updated metrics available"
593
+ ];
594
+ item.recent_messages.unshift(messages[Math.floor(Math.random() * messages.length)]);
595
+
596
+ // Update report
597
+ item.report = `Rerun completed at ${new Date().toISOString().substring(11, 19)}. ` +
598
+ (item.risk_level === 1 ? "No issues detected." :
599
+ item.risk_level === 2 ? "Some warnings detected." : "Critical issues found.");
600
+ }
601
+ });
602
+
603
+ renderTable();
604
+ alert('Rerun completed for selected items!');
605
+ }, 3000);
606
+ });
607
+
608
+ selectAll.addEventListener('change', function() {
609
+ const checkboxes = document.querySelectorAll('.row-checkbox');
610
+ checkboxes.forEach(checkbox => {
611
+ checkbox.checked = this.checked;
612
+ });
613
+ });
614
+
615
+ sqrMidInput.addEventListener('input', function() {
616
+ // In a real app, this would call an API to validate the SQR MID
617
+ // For demo purposes, we'll just show a preview after 3 characters
618
+ if (this.value.length >= 3) {
619
+ // Simulate API response
620
+ const mockResponses = {
621
+ "MID": {
622
+ name: "Payment Gateway",
623
+ description: "Main payment processing service",
624
+ image: "https://images.unsplash.com/photo-1556742049-0cfed4f6a45d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
625
+ recent_message: "Transaction processed successfully"
626
+ },
627
+ "INV": {
628
+ name: "Inventory Service",
629
+ description: "Product inventory management",
630
+ image: "https://images.unsplash.com/photo-1556740738-b6a63e27c4df?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
631
+ recent_message: "Warning: Low stock detected for SKU-4567"
632
+ },
633
+ "CUS": {
634
+ name: "Customer API",
635
+ description: "Customer data access endpoint",
636
+ image: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
637
+ recent_message: "ERROR: Authentication failure rate at 12%"
638
+ },
639
+ "ORD": {
640
+ name: "Order Processing",
641
+ description: "Order fulfillment pipeline",
642
+ image: "https://images.unsplash.com/photo-1556742044-3c52d6e88c62?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80",
643
+ recent_message: "Warning: Processing queue backlog of 125 orders"
644
+ }
645
+ };
646
+
647
+ const prefix = this.value.substring(0, 3).toUpperCase();
648
+ const mockData = mockResponses[prefix] || {
649
+ name: `Service ${this.value}`,
650
+ description: `Description for service ${this.value}`,
651
+ image: "https://via.placeholder.com/150/008000/FFFFFF",
652
+ recent_message: `Initializing monitoring for ${this.value}`
653
+ };
654
+
655
+ document.getElementById('previewImage').src = mockData.image;
656
+ document.getElementById('previewName').textContent = mockData.name;
657
+ document.getElementById('previewDesc').textContent = mockData.description;
658
+ document.getElementById('previewMessage').textContent = mockData.recent_message;
659
+ previewSection.classList.remove('hidden');
660
+ } else {
661
+ previewSection.classList.add('hidden');
662
+ }
663
+ });
664
+
665
+ confirmAddBtn.addEventListener('click', function() {
666
+ const sqrMid = sqrMidInput.value.trim();
667
+ if (!sqrMid) {
668
+ alert('Please enter a valid SQR MID');
669
+ return;
670
+ }
671
+
672
+ // Check if already exists
673
+ if (monitoringData.some(item => item.sqr_mid === sqrMid)) {
674
+ alert('This SQR MID is already being monitored');
675
+ return;
676
+ }
677
+
678
+ // Add new monitoring item
679
+ const newItem = {
680
+ sqr_mid: sqrMid,
681
+ name: document.getElementById('previewName').textContent || `Service ${sqrMid}`,
682
+ description: document.getElementById('previewDesc').textContent || `Monitoring for ${sqrMid}`,
683
+ image: document.getElementById('previewImage').src || "https://via.placeholder.com/150/008000/FFFFFF",
684
+ risk_level: 1,
685
+ recent_messages: [
686
+ document.getElementById('previewMessage').textContent || `Monitoring started for ${sqrMid}`
687
+ ],
688
+ report: `Initial monitoring report for ${sqrMid}. No issues detected.`,
689
+ last_updated: new Date().toISOString().replace('T', ' ').substring(0, 19),
690
+ status: "ready",
691
+ config: {
692
+ interval: 1,
693
+ message_count: 10
694
+ }
695
+ };
696
+
697
+ monitoringData.push(newItem);
698
+ renderTable();
699
+
700
+ // Reset and close modal
701
+ sqrMidInput.value = '';
702
+ previewSection.classList.add('hidden');
703
+ addModal.classList.add('hidden');
704
+
705
+ alert(`Successfully added monitoring for ${sqrMid}`);
706
+ });
707
+
708
+ // Initial render
709
+ renderTable();
710
+ </script>
711
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=vrvrv/monitoring-dashboard" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
712
+ </html>