Skip to content

Commit bfc9ef1

Browse files
author
Tom Softreck
committed
update
1 parent 85d0134 commit bfc9ef1

File tree

6 files changed

+188
-199
lines changed

6 files changed

+188
-199
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,17 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
256256

257257
Made with ❤️ for system administrators and developers who love comprehensive, visual tools.
258258

259-
**Version 2.0.0** - Now with file browsing and transparency layers!
259+
**Version 2.0.0** - Now with file browsing and transparency layers!
260+
261+
### webtask-2
262+
263+
#### List
264+
![webtask-list.png](webtask-list.png)
265+
266+
267+
#### Grid
268+
![webtask-grid.png](webtask-grid.png)
269+
270+
271+
### webtask-1
272+
![webtask-1.png](webtask-1.png)

webtask-1.png

94.4 KB
Loading

webtask/static/index.html

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<div class="cpu-section">
1717
<div class="cpu-header">
1818
<span>CPU: <span id="cpu-percent">0%</span></span>
19-
<span class="cpu-cores-count">(<span id="cpu-cores-count">4</span> cores)</span>
19+
<!-- <span class="cpu-cores-count">(<span id="cpu-cores-count">4</span> cores)</span>-->
2020
</div>
2121
<div class="cpu-cores-container" id="cpu-cores-container">
2222
<!-- CPU cores will be dynamically generated here -->
@@ -97,10 +97,6 @@
9797

9898
<div class="main-content">
9999
<div class="process-controls">
100-
<div class="view-options">
101-
<button class="view-option active" data-view="grid">Grid View</button>
102-
<button class="view-option" data-view="list">List View</button>
103-
</div>
104100
<div class="sort-options">
105101
<label>Sort by:</label>
106102
<select id="sort-select">

webtask/static/js/modules/system-monitor.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ class SystemMonitor {
253253
const coreElement = document.createElement('div');
254254
coreElement.className = 'cpu-core';
255255
coreElement.innerHTML = `
256-
<div class="core-label">Core ${i + 1}</div>
256+
<!-- <div class="core-label">${i + 1}</div>-->
257257
<div class="core-bar">
258258
<div class="core-fill" id="core-fill-${i}" style="width: 0%"></div>
259259
</div>
@@ -317,8 +317,9 @@ class SystemMonitor {
317317

318318
if (fillElement && valueElement) {
319319
fillElement.style.width = `${coreLoad}%`;
320-
valueElement.textContent = `${coreLoad.toFixed(1)}%`;
321-
320+
valueElement.textContent = `${coreLoad.toFixed(0)}%`;
321+
// valueElement.textContent = `${coreLoad.toFixed(1)}%`;
322+
322323
// Update color based on load
323324
if (coreLoad < 50) {
324325
fillElement.style.backgroundColor = '#00ffff';

webtask/static/js/modules/ui-manager.js

Lines changed: 99 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -237,31 +237,32 @@ class UIManager {
237237
*/
238238
generateCommandWithIcon(process) {
239239
let iconHtml = '';
240+
const command = process.command || '';
240241

241242
// Determine the type of icon based on the process service or command
242243
if (process.service === 'nginx') {
243244
iconHtml = '<span class="command-icon nginx-icon">NGINX</span>';
244245
} else if (process.service === 'node') {
245246
iconHtml = '<span class="command-icon node-icon">NODE</span>';
246-
} else if (process.service === 'python' || process.command.includes('python')) {
247+
} else if (process.service === 'python' || command.includes('python')) {
247248
iconHtml = '<span class="command-icon python-icon">PY</span>';
248-
} else if (process.service === 'java' || process.command.includes('java')) {
249+
} else if (process.service === 'java' || command.includes('java')) {
249250
iconHtml = '<span class="command-icon java-icon">JAVA</span>';
250-
} else if (process.service === 'mysql' || process.command.includes('mysql')) {
251+
} else if (process.service === 'mysql' || command.includes('mysql')) {
251252
iconHtml = '<span class="command-icon mysql-icon">SQL</span>';
252-
} else if (process.command.includes('firefox')) {
253+
} else if (command.includes('firefox')) {
253254
iconHtml = '<span class="command-icon firefox-icon">FF</span>';
254-
} else if (process.command.includes('chrome')) {
255+
} else if (command.includes('chrome')) {
255256
iconHtml = '<span class="command-icon chrome-icon">CR</span>';
256-
} else if (process.command.includes('pycharm')) {
257+
} else if (command.includes('pycharm')) {
257258
iconHtml = '<span class="command-icon pycharm-icon">PC</span>';
258-
} else if (process.command.includes('vscode') || process.command.includes('code')) {
259+
} else if (command.includes('vscode') || command.includes('code')) {
259260
iconHtml = '<span class="command-icon vscode-icon">VS</span>';
260261
} else {
261262
iconHtml = '<span class="command-icon process-icon">PROC</span>';
262263
}
263264

264-
return `<div class="command-with-icon">${iconHtml} <span class="command-text">${process.command}</span></div>`;
265+
return `<div class="command-with-icon">${iconHtml} <span class="command-text">${command}</span></div>`;
265266
}
266267

267268
/**
@@ -270,183 +271,108 @@ class UIManager {
270271
* @returns {string} HTML for the preview thumbnail
271272
*/
272273
generatePreviewThumbnail(process) {
273-
let thumbnailContent = '';
274-
let thumbnailClass = 'preview-thumbnail';
275-
276-
// Generate command icon for use in thumbnails
277-
const commandIcon = this.generateCommandWithIcon(process);
278-
279-
// Determine the type of preview based on the process
280-
if (process.file) {
281-
// Get file content from fileSystemManager if available, otherwise use local method
282-
const fileContent = this.fileSystemManager ?
283-
this.fileSystemManager.getFileContent(process.file) :
284-
this.getFileContent(process.file);
285-
286-
if (fileContent) {
287-
if (process.file.endsWith('.html')) {
288-
thumbnailContent = `
289-
<div class="html-preview">
290-
<div class="text-preview-header">
291-
<span>${commandIcon}</span>
292-
<span class="file-icon" style="background: #e34c26; color: white;">HTML</span>
293-
<span>${process.file.split('/').pop()}</span>
294-
</div>
295-
<iframe srcdoc="${this.escapeHTML(fileContent)}"></iframe>
296-
</div>
297-
`;
298-
} else if (process.file.endsWith('.js')) {
299-
thumbnailContent = `
300-
<div class="code-preview">
301-
<div class="code-preview-header">
302-
<span>${commandIcon}</span>
303-
<span class="file-icon" style="background: #f7df1e; color: #000;">JS</span>
304-
<span>${process.file.split('/').pop()}</span>
305-
</div>
306-
<pre class="code-snippet">${this.escapeHTML(fileContent.substring(0, 100))}${fileContent.length > 100 ? '...' : ''}</pre>
307-
</div>
308-
`;
309-
} else if (process.file.endsWith('.css')) {
310-
thumbnailContent = `
311-
<div class="code-preview">
312-
<div class="code-preview-header">
313-
<span>${commandIcon}</span>
314-
<span class="file-icon" style="background: #264de4; color: white;">CSS</span>
315-
<span>${process.file.split('/').pop()}</span>
316-
</div>
317-
<pre class="code-snippet">${this.escapeHTML(fileContent.substring(0, 100))}${fileContent.length > 100 ? '...' : ''}</pre>
318-
</div>
319-
`;
320-
} else if (process.file.endsWith('.json')) {
321-
thumbnailContent = `
322-
<div class="code-preview">
323-
<div class="code-preview-header">
324-
<span>${commandIcon}</span>
325-
<span class="file-icon" style="background: #000; color: white;">JSON</span>
326-
<span>${process.file.split('/').pop()}</span>
327-
</div>
328-
<pre class="code-snippet">${this.escapeHTML(fileContent.substring(0, 100))}${fileContent.length > 100 ? '...' : ''}</pre>
329-
</div>
330-
`;
331-
} else if (process.file.endsWith('.sh') || process.file.endsWith('.bash')) {
332-
thumbnailContent = `
333-
<div class="code-preview">
334-
<div class="code-preview-header">
335-
<span>${commandIcon}</span>
336-
<span class="file-icon" style="background: #4EAA25; color: white;">BASH</span>
337-
<span>${process.file.split('/').pop()}</span>
338-
</div>
339-
<pre class="code-snippet">${this.escapeHTML(fileContent.substring(0, 100))}${fileContent.length > 100 ? '...' : ''}</pre>
340-
</div>
341-
`;
342-
} else if (/\.(jpg|jpeg|png|gif|svg)$/i.test(process.file)) {
343-
thumbnailContent = `
344-
<div class="text-preview">
345-
<div class="text-preview-header">
346-
<span>${commandIcon}</span>
347-
<span class="file-icon" style="background: #f06; color: white;">IMG</span>
348-
<span>${process.file.split('/').pop()}</span>
349-
</div>
350-
<div class="text-content">Image file</div>
351-
</div>
352-
`;
353-
} else if (process.file.endsWith('.pdf')) {
354-
thumbnailContent = `
355-
<div class="text-preview">
356-
<div class="text-preview-header">
357-
<span>${commandIcon}</span>
358-
<span class="file-icon" style="background: #f40f02; color: white;">PDF</span>
359-
<span>${process.file.split('/').pop()}</span>
360-
</div>
361-
<div class="text-content">PDF Document</div>
362-
</div>
363-
`;
364-
} else if (process.file.endsWith('.txt') || process.file.endsWith('.md') || process.file.endsWith('.log')) {
365-
thumbnailContent = `
366-
<div class="text-preview">
367-
<div class="text-preview-header">
368-
<span>${commandIcon}</span>
369-
<span class="file-icon" style="background: #eee; color: #333;">TXT</span>
370-
<span>${process.file.split('/').pop()}</span>
371-
</div>
372-
<div class="text-content">${this.escapeHTML(fileContent.substring(0, 200))}${fileContent.length > 200 ? '...' : ''}</div>
373-
</div>
374-
`;
375-
}
376-
}
377-
}
378-
// Check if this is a web service
379-
else if (process.command && (process.command.includes('nginx') || process.command.includes('apache') || process.command.includes('http'))) {
380-
thumbnailContent = `
381-
<div class="web-service-preview">
382-
<div class="web-service-header">
383-
<span>${commandIcon}</span>
384-
${process.port ? `<span class="port-badge">:${process.port}</span>` : ''}
385-
</div>
386-
<div class="browser-mockup">
387-
<div class="browser-bar"></div>
388-
<div class="browser-content"></div>
274+
// Create metrics visualization that will be used in all previews
275+
const metricsHTML = `
276+
<div class="process-metrics">
277+
<div class="metric-item">
278+
<div class="metric-label">CPU</div>
279+
<div class="metric-value">${process.cpu.toFixed(1)}%</div>
280+
<div class="metric-bar">
281+
<div class="metric-fill cpu-fill" style="width: ${Math.min(process.cpu, 100)}%"></div>
389282
</div>
390283
</div>
391-
`;
392-
}
393-
// Check if this is a database service
394-
else if (process.command && (process.command.includes('mysql') || process.command.includes('postgres') || process.command.includes('mongo'))) {
395-
thumbnailContent = `
396-
<div class="service-preview">
397-
<div class="service-header">
398-
<span>${commandIcon}</span>
399-
</div>
400-
<div class="service-content">
401-
<div class="service-status">Running</div>
402-
<div class="service-metrics">
403-
<div class="metric">CPU: ${process.cpu.toFixed(1)}%</div>
404-
<div class="metric">MEM: ${process.memory.toFixed(1)}%</div>
405-
</div>
284+
<div class="metric-item">
285+
<div class="metric-label">MEM</div>
286+
<div class="metric-value">${process.memory.toFixed(1)}%</div>
287+
<div class="metric-bar">
288+
<div class="metric-fill mem-fill" style="width: ${Math.min(process.memory, 100)}%"></div>
406289
</div>
407290
</div>
408-
`;
409-
}
410-
// Check if this is a port listener
411-
else if (process.port) {
412-
thumbnailContent = `
413-
<div class="port-preview">
414-
<div class="port-header">
415-
<span>${commandIcon}</span>
416-
<span class="port-badge">:${process.port}</span>
291+
</div>
292+
`;
293+
294+
// Check if this is a web service (has a port)
295+
if (process.port) {
296+
return `
297+
<div class="web-service-preview">
298+
<div class="preview-header">
299+
<span class="preview-title">Web Service on Port ${process.port}</span>
417300
</div>
418-
<div class="port-details">
419-
<div class="port-status active"></div>
420-
<div class="port-info">TCP ${process.port}</div>
301+
<div class="preview-content">
302+
<div class="port-badge">:${process.port}</div>
303+
${metricsHTML}
421304
</div>
422305
</div>
423306
`;
424307
}
425-
// Generic process
426-
else if (process.command) {
427-
thumbnailContent = `
428-
<div class="generic-preview">
429-
<div class="process-header">
430-
<span>${commandIcon}</span>
431-
<span class="process-pid">${process.pid}</span>
432-
</div>
433-
<div class="process-content">
434-
<div class="process-command">${this.escapeHTML(process.command)}</div>
435-
<div class="process-metrics">
436-
<div class="metric">CPU: ${process.cpu.toFixed(1)}%</div>
437-
<div class="metric">MEM: ${process.memory.toFixed(1)}%</div>
308+
309+
// Check if this is a text file
310+
const command = process.command || '';
311+
if (command.match(/\.(txt|md|log|json|js|py|html|css)$/i)) {
312+
const fileType = command.split('.').pop().toLowerCase();
313+
let fileContent = '';
314+
315+
try {
316+
if (this.fileSystemManager) {
317+
fileContent = this.fileSystemManager.getFileContent(command);
318+
319+
// Handle HTML content differently
320+
if (fileType === 'html') {
321+
return `
322+
<div class="html-preview">
323+
<div class="preview-header">
324+
<span class="preview-title">HTML Preview</span>
325+
</div>
326+
<iframe srcdoc="${fileContent.replace(/"/g, '&quot;')}" style="width:100%; height:70%; transform: scale(0.2); transform-origin: 0 0; border: none;"></iframe>
327+
${metricsHTML}
328+
</div>
329+
`;
330+
}
331+
332+
// For code files, show syntax highlighted preview
333+
if (['js', 'py', 'css', 'json'].includes(fileType)) {
334+
return `
335+
<div class="code-preview">
336+
<div class="preview-header">
337+
<span class="preview-title">${fileType.toUpperCase()} File</span>
338+
</div>
339+
<pre class="code-content ${fileType}-content">${fileContent.substring(0, 100)}${fileContent.length > 100 ? '...' : ''}</pre>
340+
${metricsHTML}
341+
</div>
342+
`;
343+
}
344+
345+
// For other text files
346+
return `
347+
<div class="text-preview">
348+
<div class="preview-header">
349+
<span class="preview-title">Text File</span>
350+
</div>
351+
<div class="text-content">${fileContent.substring(0, 100)}${fileContent.length > 100 ? '...' : ''}</div>
352+
${metricsHTML}
438353
</div>
439-
</div>
440-
</div>
441-
`;
354+
`;
355+
}
356+
} catch (error) {
357+
console.error('Error generating preview for file:', error);
358+
}
442359
}
443360

444-
// Wrap the content in a div with the appropriate class
445-
if (thumbnailContent) {
446-
return `<div class="${thumbnailClass}" data-pid="${process.pid}">${thumbnailContent}</div>`;
447-
}
448-
449-
return '';
361+
// Generate command icon for use in thumbnails
362+
const commandIcon = this.generateCommandWithIcon(process);
363+
364+
// Default generic preview
365+
return `
366+
<div class="generic-preview">
367+
<div class="preview-header">
368+
<span class="preview-title"></span>
369+
</div>
370+
<div class="preview-content">
371+
<div class="command-display">${commandIcon}</div>
372+
${metricsHTML}
373+
</div>
374+
</div>
375+
`;
450376
}
451377

452378
/**

0 commit comments

Comments
 (0)