bitunix-automated-crypto-trading 2.6.7__py3-none-any.whl → 2.6.8__py3-none-any.whl

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.
Files changed (31) hide show
  1. bitunix_automated_crypto_trading/AsyncThreadRunner.py +81 -81
  2. bitunix_automated_crypto_trading/BitunixApi.py +278 -278
  3. bitunix_automated_crypto_trading/BitunixSignal.py +1099 -1099
  4. bitunix_automated_crypto_trading/BitunixWebSocket.py +254 -254
  5. bitunix_automated_crypto_trading/DataFrameHtmlRenderer.py +74 -74
  6. bitunix_automated_crypto_trading/NotificationManager.py +23 -23
  7. bitunix_automated_crypto_trading/ThreadManager.py +68 -68
  8. bitunix_automated_crypto_trading/TickerManager.py +635 -635
  9. bitunix_automated_crypto_trading/bitunix.py +597 -594
  10. bitunix_automated_crypto_trading/config.py +90 -90
  11. bitunix_automated_crypto_trading/logger.py +84 -84
  12. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/METADATA +36 -36
  13. bitunix_automated_crypto_trading-2.6.8.dist-info/RECORD +17 -0
  14. bitunix_automated_crypto_trading/config.txt +0 -60
  15. bitunix_automated_crypto_trading/sampleenv.txt +0 -5
  16. bitunix_automated_crypto_trading/static/chart.css +0 -28
  17. bitunix_automated_crypto_trading/static/chart.js +0 -362
  18. bitunix_automated_crypto_trading/static/modal.css +0 -68
  19. bitunix_automated_crypto_trading/static/modal.js +0 -147
  20. bitunix_automated_crypto_trading/static/script.js +0 -166
  21. bitunix_automated_crypto_trading/static/styles.css +0 -118
  22. bitunix_automated_crypto_trading/templates/charts.html +0 -98
  23. bitunix_automated_crypto_trading/templates/login.html +0 -19
  24. bitunix_automated_crypto_trading/templates/main.html +0 -551
  25. bitunix_automated_crypto_trading/templates/modal-chart.html +0 -26
  26. bitunix_automated_crypto_trading/templates/modal-config.html +0 -34
  27. bitunix_automated_crypto_trading/templates/modal-logs.html +0 -15
  28. bitunix_automated_crypto_trading-2.6.7.dist-info/RECORD +0 -31
  29. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/WHEEL +0 -0
  30. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/entry_points.txt +0 -0
  31. {bitunix_automated_crypto_trading-2.6.7.dist-info → bitunix_automated_crypto_trading-2.6.8.dist-info}/top_level.txt +0 -0
@@ -1,551 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
-
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Bitunix Auto Trading</title>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
- <script src="https://cdn.jsdelivr.net/npm/chartjs-chart-financial"></script>
10
- <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns"></script>
11
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
12
- <link rel="stylesheet" href="static/styles.css">
13
- <link rel="stylesheet" href="static/modal.css">
14
- <link rel="stylesheet" href="static/chart.css">
15
- <style>
16
-
17
- .mainbody {
18
- flex: 1;
19
- margin-top: 1px; /* Adjust this value according to the height of your header */
20
- margin-bottom: 60px; /* Adjust this value according to the height of your footer */
21
- overflow-y: auto;
22
- padding: 1em;
23
- }
24
- </style>
25
- </head>
26
- <body>
27
- <div class="mainbody">
28
- <div class="row">
29
- <div id="portfolio">
30
- Loading portfolio value...
31
- </div>
32
- </div>
33
- <div class="container">
34
- <div class="right">
35
- <label for="optionMovingAverage">Moving Average</label>
36
- <select disabled id="optionMovingAverage">
37
- <option value="1d">Daily</option>
38
- <option value="1h">Hourly</option>
39
- <option value="15m">15 minutes</option>
40
- <option value="5m">5 minutes</option>
41
- <option value="1m">1 minutes</option>
42
- </select>
43
- </div>
44
- <div class="right">
45
- <label for="maxAutoTrades">MaxAutoTrades</label>
46
- <input disabled type="text" id="maxAutoTrades">
47
- </div>
48
- <div class="right">
49
- <label for="autoTrade">AutoTrade</label>
50
- <input disabled type="checkbox" id="autoTrade" name="AutoTrade">
51
- </div>
52
- <div class="right">
53
- <label for="totalProfit">Total Profit</label>
54
- <div id="totalProfit">...</div>
55
- </div>
56
- <div class="left">
57
- <label for="tickerDataCycleTime">Ticker Data Last Cycle</label>
58
- <div id="tickerDataCycleTime">...</div>
59
- </div>
60
- <div class="left">
61
- <label for="autoTradeCycleTime">AutoTrade Last Cycle</label>
62
- <div id="autoTradeCycleTime">...</div>
63
- </div>
64
- <div class="right">
65
- <button id="config">Config</button>
66
- </div>
67
- </div>
68
-
69
- <div id="modal-container-wrapper"></div>
70
-
71
- <span>Positions</span>
72
- <div class="row">
73
- <div id="positions">
74
- Loading positions...
75
- </div>
76
- </div>
77
- <span>orders</span>
78
- <div class="row">
79
- <div id="orders">
80
- Loading orders...
81
- </div>
82
- </div>
83
- <span>selected signals</span>
84
- <div class="row">
85
- <div id="signals">
86
- Loading signals...
87
- </div>
88
- </div>
89
- <span>all signals</span>
90
- <div class="row">
91
- <div id="study">
92
- Loading signals...
93
- </div>
94
- </div>
95
- <span>positionHistory</span>
96
- <div class="row">
97
- <div id="positionHistory">
98
- Loading positionHistory...
99
- </div>
100
- </div>
101
- </div>
102
- <footer>
103
- <div class="dropdown">
104
- <!-- <div id="message" class="message" onclick="toggleDropdown()"></div> -->
105
- <div id="message" class="message"></div>
106
- <div id="dropdown-content" class="dropdown-content">
107
- <!-- Additional messages will be inserted here -->
108
- </div>
109
- </div>
110
- </footer>
111
-
112
- <script src="/static/modal.js"></script>
113
- <script src="/static/script.js"></script>
114
- <script src="/static/chart.js"></script>
115
- <script>
116
-
117
- ///////////////////////////////////////////////////////////////////////////////////////////
118
- //display the main screen with portfoio, positions, order, signals, positionhistory
119
- ///////////////////////////////////////////////////////////////////////////////////////////
120
-
121
- const host = window.location.hostname;
122
- const websocket_m = new WebSocket(`ws://${host}:8000/wsmain`);
123
- websocket_m.onopen = function() {
124
- document.getElementById('message').innerHTML = "main page webSocket connection opened"
125
- //Send a ping every 30 seconds
126
- setInterval(()=>{
127
- if (websocket_m.readyState === WebSocket.OPEN) {
128
- websocket_m.send("ping");
129
- }
130
- }, 30000);
131
- }
132
-
133
- websocket_m.onmessage = function(event) {
134
- if (event.data === "pong") {
135
- return;
136
- }
137
-
138
- const messageElement = JSON.parse(event.data);
139
- document.getElementById("portfolio").innerHTML = messageElement.dataframes.portfolio;
140
- document.getElementById("positions").innerHTML = messageElement.dataframes.positions;
141
- document.getElementById("orders").innerHTML = messageElement.dataframes.orders;
142
- document.getElementById("signals").innerHTML = messageElement.dataframes.signals;
143
- document.getElementById("study").innerHTML = messageElement.dataframes.study;
144
- document.getElementById("positionHistory").innerHTML = messageElement.dataframes.positionHistory;
145
- document.getElementById('message').innerHTML = messageElement.status_messages;
146
-
147
- document.getElementById('totalProfit').innerText = messageElement.profit;
148
- document.getElementById("autoTradeCycleTime").innerText = messageElement.atctime;
149
- document.getElementById("tickerDataCycleTime").innerText = messageElement.tdctime;
150
- const messages = messageElement.status_messages;
151
- displayNotifications(messages)
152
-
153
- const currentTime = new Date();
154
- if (messageElement.atctime) {
155
- const atctime = new Date(messageElement.atctime);
156
- const atctime1 = Math.abs(currentTime - atctime) / (1000 * 60);
157
- if (atctime1 > 5) {
158
- document.getElementById("autoTradeCycleTime").style.color = "red";
159
- } else {
160
- document.getElementById("autoTradeCycleTime").style.color = "black";
161
- }
162
- }
163
- if (messageElement.tdctime) {
164
- const tdctime = new Date(messageElement.tdctime);
165
- const tdctime1 = Math.abs(currentTime - tdctime) / (1000 * 60);
166
- if (tdctime1 > 5) {
167
- document.getElementById("tickerDataCycleTime").style.color = "red";
168
- } else {
169
- document.getElementById("tickerDataCycleTime").style.color = "black";
170
- }
171
- }
172
- };
173
-
174
-
175
- websocket_m.onerror = function(error) {
176
- document.getElementById('message').innerHTML = "main page webSocket connection failed.";
177
- };
178
-
179
- websocket_m.onclose = function() {
180
- document.getElementById('message').innerHTML = "main page webSocket connection closed.";
181
- };
182
-
183
-
184
- window.onload = async function() {
185
- const payload = {element_ids:['autoTrade', 'optionMovingAverage', 'maxAutoTrades']};
186
- await fetchStates(payload);
187
- };
188
-
189
- document.getElementById("autoTrade").addEventListener('change', async function() {
190
- const states = {
191
- autoTrade: document.getElementById('autoTrade').checked.toString(),
192
- optionMovingAverage: document.getElementById('optionMovingAverage').value,
193
- profitAmount: document.getElementById('profitAmount').value,
194
- lossAmount: document.getElementById('lossAmount').value,
195
- maxAutoTrades: document.getElementById('maxAutoTrades').value
196
- };
197
- await saveStates(states);
198
-
199
- const response = await fetch('/autotrade', {
200
- method: 'POST',
201
- headers: {
202
- 'Content-Type': 'application/x-www-form-urlencoded',
203
- },
204
- body: JSON.stringify({ 'autoTrade': autoTrade })
205
- });
206
- });
207
-
208
-
209
- async function handleChartsButton(symbol) {
210
- const response = await fetch('/handle_charts_click', {
211
- method: 'POST',
212
- headers: {
213
- 'Content-Type': 'application/x-www-form-urlencoded',
214
- },
215
- body: `symbol=${encodeURIComponent(symbol)}`
216
- });
217
- const result = await response.json();
218
- openURL(result.message);
219
- }
220
-
221
- async function handleBitunixButton(symbol) {
222
- const response = await fetch('/handle_bitunix_click', {
223
- method: 'POST',
224
- headers: {
225
- 'Content-Type': 'application/x-www-form-urlencoded',
226
- },
227
- body: `symbol=${symbol}`
228
- });
229
- const result = await response.json();
230
- openURL(result.message);
231
- }
232
-
233
- async function handleAddButton(symbol,close) {
234
- let result1 = confirm("Add "+ symbol + " @ " + close.toString());
235
- if (result1) {
236
- const response = await fetch('/handle_add_click', {
237
- method: 'POST',
238
- headers: {
239
- 'Content-Type': 'application/x-www-form-urlencoded',
240
- },
241
- body: `symbol=${encodeURIComponent(symbol)}&close=${encodeURIComponent(close)}`
242
- });
243
- }
244
- }
245
-
246
- async function handleReduceButton(symbol,positionId,qty,close) {
247
- let result1 = confirm("Reduce "+ symbol + " @ " + close.toString());
248
- if (result1) {
249
- const response = await fetch('/handle_reduce_click', {
250
- method: 'POST',
251
- headers: {
252
- 'Content-Type': 'application/x-www-form-urlencoded',
253
- },
254
- body: `symbol=${encodeURIComponent(symbol)}&positionId=${encodeURIComponent(positionId)}&qty=${encodeURIComponent(qty)}&close=${encodeURIComponent(close)}`
255
- });
256
- }
257
- }
258
-
259
- async function handleBuyButton(symbol,close) {
260
- let result1 = confirm("Buy "+ symbol + " @ " + close.toString());
261
- if (result1) {
262
- const response = await fetch('/handle_buy_click', {
263
- method: 'POST',
264
- headers: {
265
- 'Content-Type': 'application/x-www-form-urlencoded',
266
- },
267
- body: `symbol=${encodeURIComponent(symbol)}&close=${encodeURIComponent(close)}`
268
- });
269
- }
270
- }
271
-
272
- async function handleSellButton(symbol,close) {
273
- let result2 = confirm("Sell "+ symbol + " @ " + close.toString());
274
- if (result2) {
275
- const response = await fetch('/handle_sell_click', {
276
- method: 'POST',
277
- headers: {
278
- 'Content-Type': 'application/x-www-form-urlencoded',
279
- },
280
- body: `symbol=${encodeURIComponent(symbol)}&close=${encodeURIComponent(close)}`
281
- });
282
- }
283
- }
284
-
285
- async function handleCloseButton(symbol,positionId,qty,unrealizedPNL,realizedPNL) {
286
- let result3 = confirm("Close Position "+ symbol + " with positionid: " + positionId );
287
- if (result3) {
288
- const response = await fetch('/handle_close_click', {
289
- method: 'POST',
290
- headers: {
291
- 'Content-Type': 'application/x-www-form-urlencoded',
292
- },
293
- body: `symbol=${encodeURIComponent(symbol)}&positionId=${encodeURIComponent(positionId)}&qty=${encodeURIComponent(qty)}&unrealizedPNL=${encodeURIComponent(unrealizedPNL)}&realizedPNL=${encodeURIComponent(realizedPNL)}`
294
- });
295
- }
296
- }
297
-
298
- async function handleOrderCloseButton(symbol,orderId) {
299
- let result3 = confirm("Close Order "+ symbol + " with orderid: " + orderId );
300
- if (result3) {
301
- const response = await fetch('/handle_order_close_click', {
302
- method: 'POST',
303
- headers: {
304
- 'Content-Type': 'application/x-www-form-urlencoded',
305
- },
306
- body: `symbol=${encodeURIComponent(symbol)}&orderId=${encodeURIComponent(orderId)}`
307
- });
308
- }
309
- }
310
-
311
-
312
- async function handleRowClick(name) {
313
- const response = await fetch('/handle_click', {
314
- method: 'POST',
315
- headers: {
316
- 'Content-Type': 'application/x-www-form-urlencoded',
317
- },
318
- body: `name=${name}`
319
- });
320
- const result = await response.json();
321
- openURL(result.message);
322
- }
323
-
324
-
325
- ///////////////////////////////////////////////////////////////////////////////////////////
326
- //display config modal window
327
- ///////////////////////////////////////////////////////////////////////////////////////////
328
- //open modal config html
329
- document.getElementById("config").addEventListener('click', () => {
330
- handleConfigButton();
331
- });
332
-
333
- // Open modal and fetch its content
334
- async function handleConfigButton() {
335
- try{
336
- // Fetch modal content
337
- const modalContainerWrapper = document.getElementById('modal-container-wrapper'); const modalResponse = await fetch('/config');
338
- const modalConfigResponse = await fetch('/config');
339
- if (!modalConfigResponse.ok) throw new Error("Failed to fetch config.html");
340
- modalContainerWrapper.innerHTML = await modalConfigResponse.text();
341
-
342
- // Fetch environment variables
343
- const configResponse = await fetch('/get-config');
344
- if (!configResponse.ok) throw new Error("Failed to fetch config variables");
345
- const configVars = await configResponse.json();
346
-
347
- // initialize modal
348
- configModal = initializeModal('modal-container', 'modal-overlay', 'modal', {
349
- top : '10%',
350
- left : '10%',
351
- width : '80%',
352
- height : '80%',
353
- maxWidth : '80vw',
354
- maxHeight : '100vh',
355
- allowMove: false,
356
- allowResize: false,
357
- onClose: () => {}
358
- });
359
-
360
- //open config modal
361
- configModal.open()
362
-
363
- // Populate the table
364
- const tbody = document.querySelector('#config-table tbody');
365
- if (!tbody) throw new Error("<tbody> element not found");
366
- tbody.innerHTML = Object.entries(configVars)
367
- .map(([key, value]) =>
368
- `<tr class="config-item" data-key="${key}" data-value="${value}">
369
- <td>${key}</td>
370
- <td>${value}</td>
371
- </tr>`
372
- )
373
- .join('');
374
-
375
- // Add click event listener to each environment variable
376
- document.querySelectorAll('.config-item').forEach((item) => {
377
- item.addEventListener('click', () => {
378
- const key = item.getAttribute('data-key');
379
- const value = item.getAttribute('data-value');
380
- document.getElementById('key').value = key;
381
- document.getElementById('value').value = value;
382
- });
383
- });
384
-
385
- // Handle save form submission
386
- const saveForm = document.getElementById('save-config-form');
387
- saveForm.addEventListener('submit', async (e) => {
388
- e.preventDefault();
389
- const formData = new FormData(saveForm);
390
- const saveResponse = await fetch('/save-config', {
391
- method: 'POST',
392
- body: formData,
393
- });
394
- const saveResult = await saveResponse.json();
395
- alert(saveResult.message);
396
-
397
- //update variable on the screen
398
- const payload = {element_ids:['autoTrade', 'optionMovingAverage', 'maxAutoTrades']};
399
- fetchStates(payload);
400
-
401
- handleConfigButton(); // Reload modal content after saving changes
402
- });
403
-
404
- } catch (error) {
405
- console.error('Error:', error);
406
- }
407
- }
408
-
409
- ///////////////////////////////////////////////////////////////////////////////////////////
410
- //display logs modal window
411
- ///////////////////////////////////////////////////////////////////////////////////////////
412
- document.getElementById("message").addEventListener('click', () => {
413
- handleMessageArea();
414
- });
415
-
416
- // Open modal and fetch its content
417
- async function handleMessageArea() {
418
- try {
419
- // Fetch modal content
420
- const modalContainerWrapper = document.getElementById('modal-container-wrapper'); const modalResponse = await fetch('/config');
421
- const modalLogsResponse = await fetch('/logs');
422
- if (!modalLogsResponse.ok) throw new Error("Failed to fetch log.html");
423
- modalContainerWrapper.innerHTML = await modalLogsResponse.text();
424
-
425
- // initialize modal
426
- configModal = initializeModal('modal-container', 'modal-overlay', 'modal', {
427
- top : '10%',
428
- left : '10%',
429
- width : '80%',
430
- height : '80%',
431
- maxWidth : '80vw',
432
- maxHeight : '80vh',
433
- allowMove: false,
434
- allowResize: false,
435
- onClose: () => {
436
- websocket_l.close();
437
- }
438
- });
439
-
440
- //open config modal
441
- configModal.open()
442
-
443
- const logContainer = document.getElementById('log-container');
444
- logContainer.innerText = '';
445
-
446
- // Open WebSocket connection
447
- const websocket_l = new WebSocket(`ws://${host}:8000/wslogs`);
448
-
449
- websocket_l.onopen = () => {
450
- console.log("log WebSocket connection opened.");
451
- };
452
-
453
- websocket_l.onmessage = (event) => {
454
- logContainer.innerText += event.data + '\n'; // Append new log
455
- logContainer.scrollTop = logContainer.scrollHeight; // Auto-scroll
456
- };
457
-
458
- websocket_l.onclose = () => {
459
- console.log("log WebSocket connection closed.");
460
- };
461
-
462
-
463
- } catch (error) {
464
- console.error('Error:', error);
465
- }
466
- }
467
-
468
- ///////////////////////////////////////////////////////////////////////////////////////////
469
- //display chart modal window
470
- ///////////////////////////////////////////////////////////////////////////////////////////
471
-
472
- document.addEventListener('DOMContentLoaded', (event) => {
473
- attachTableClickHandlerFunction('positions', 0, handleChart);
474
- attachTableClickHandlerFunction('orders', 0, handleChart);
475
- attachTableClickHandlerFunction('signals', 0, handleChart);
476
- attachTableClickHandlerFunction('study', 0, handleChart);
477
- attachTableClickHandlerFunction('positionHistory', 0, handleChart);
478
- });
479
-
480
- // Open modal and fetch its content
481
- async function handleChart(symbol){
482
- try {
483
- // Fetch modal content
484
- const modalContainerWrapper = document.getElementById('modal-container-wrapper'); const modalResponse = await fetch('/config');
485
- const modalChartResponse = await fetch(`/chart?symbol=${encodeURIComponent(symbol)}`);
486
- if (!modalChartResponse.ok) throw new Error("Failed to fetch chart.html");
487
- modalContainerWrapper.innerHTML = await modalChartResponse.text();
488
-
489
- // initialize modal
490
- configModal = initializeModal('modal-container', 'modal-overlay', 'modal', {
491
- top : '10%',
492
- left : '10%',
493
- width : '80%',
494
- height : '80%',
495
- maxWidth : '80vw',
496
- maxHeight : '80vw',
497
- allowMove: false,
498
- allowResize: false,
499
- onClose: () => {
500
- websocket_c2.close();
501
- delete charts['chart'];
502
- }
503
- });
504
-
505
- //open config modal
506
- configModal.open()
507
-
508
- // Open WebSocket connection
509
- const websocket_c2 = new WebSocket(`ws://${host}:8000/wschart?ticker=${symbol}`);
510
-
511
- websocket_c2.onopen = () => {
512
- console.log("chart WebSocket connection opened.");
513
- };
514
-
515
- websocket_c2.onmessage = (event) => {
516
- const messageElement = JSON.parse(event.data);
517
- document.getElementById('symbol').innerHTML = messageElement.symbol;
518
- document.getElementById('close').innerHTML = messageElement.close;
519
-
520
- const data = messageElement.chart;
521
- const buysell = messageElement.buysell;
522
- const period = messageElement.period;
523
- const ema_study = messageElement.ema_study;
524
- const ema_chart = messageElement.ema_chart;
525
- const macd_study = messageElement.macd_study;
526
- const macd_chart = messageElement.macd_chart;
527
- const bbm_study = messageElement.bbm_study;
528
- const bbm_chart = messageElement.bbm_chart;
529
- const rsi_study = messageElement.rsi_study;
530
- const rsi_chart = messageElement.rsi_chart;
531
-
532
- if (period === '1m' || period === '5m' || period === '15m') {
533
- createOrUpdateChart('chart', data, buysell, ema_study, ema_chart, macd_study, macd_chart, bbm_study, bbm_chart, rsi_study, rsi_chart, 'minute');
534
- } else if (period === '1h') {
535
- createOrUpdateChart('chart', data, buysell, ema_study, ema_chart, macd_study, macd_chart, bbm_study, bbm_chart, rsi_study, rsi_chart, 'hour');
536
- } else if (period === '1d') {
537
- createOrUpdateChart('chart', data, buysell, ema_study, ema_chart, macd_study, macd_chart, bbm_study, bbm_chart, rsi_study, rsi_chart, 'day');
538
- }
539
- };
540
-
541
- websocket_c2.onclose = () => {
542
- console.log("chart WebSocket connection closed.");
543
- };
544
-
545
- } catch (error) {
546
- console.error('Error:', error);
547
- }
548
- }
549
- </script>
550
- </body>
551
- </html>
@@ -1,26 +0,0 @@
1
- <div id="modal-overlay" class="modal-overlay">
2
- <div id="modal-container" class="modal-container">
3
- <div id="modal" class="modal">
4
- <div class="scrollable-view">
5
- <div class="container">
6
- <div class="right">
7
- <div class="label">Symbol</div>
8
- <div id='symbol'></div>
9
- </div>
10
- <div class="right">
11
- <div class="label">Close</div>
12
- <div id='close'></div>
13
- </div>
14
- </div>
15
- <div id="chart" class="chart-container">
16
- </div>
17
- </div>
18
- <div class="resize-handle resize-top-right"></div>
19
- <div class="resize-handle resize-bottom-right"></div>
20
- <div class="resize-handle resize-bottom-left"></div>
21
- <div class="resize-handle resize-top-left"></div>
22
- <button id="close-modal">Close</button>
23
- </div>
24
- </div>
25
- </div>
26
-
@@ -1,34 +0,0 @@
1
- <div id="modal-overlay" class="modal-overlay">
2
- <div id="modal-container" class="modal-container">
3
- <div id="modal" class="modal">
4
- <h1>Edit Config</h1>
5
- <div class="scrollable-view">
6
- <table id="config-table" border="1" width="100%">
7
- <thead>
8
- <tr>
9
- <th>Key</th>
10
- <th>Value</th>
11
- </tr>
12
- </thead>
13
- <tbody>
14
- <!-- Dynamically populated rows will appear here -->
15
- </tbody>
16
- </table>
17
- </div>
18
-
19
- <div class="resize-handle resize-top-right"></div>
20
- <div class="resize-handle resize-bottom-right"></div>
21
- <div class="resize-handle resize-bottom-left"></div>
22
- <div class="resize-handle resize-top-left"></div>
23
-
24
- <form id="save-config-form">
25
- <input type="text" id="key" name="key" placeholder="Key" required>
26
- <input type="text" id="value" name="value" placeholder="Value" required>
27
- <button type="submit">Save</button>
28
- </form>
29
-
30
- <button id="close-modal">Close</button>
31
- </div>
32
- </div>
33
- </div>
34
-
@@ -1,15 +0,0 @@
1
- <div id="modal-overlay" class="modal-overlay">
2
- <div id="modal-container" class="modal-container">
3
- <div id="modal" class="modal">
4
- <h1>Logs</h1>
5
- <div class="scrollable-view">
6
- <div id="log-container"></div>
7
- </div>
8
- <div class="resize-handle resize-top-right"></div>
9
- <div class="resize-handle resize-bottom-right"></div>
10
- <div class="resize-handle resize-bottom-left"></div>
11
- <div class="resize-handle resize-top-left"></div>
12
- <button id="close-modal">Close</button>
13
- </div>
14
- </div>
15
- </div>