infinite-agents-public/src_infinite/ui_hybrid_16.html

876 lines
32 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DATATERM v16.0 - Retro Computing Data Explorer</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=VT323&display=swap');
:root {
--terminal-green: #00ff00;
--terminal-amber: #ffb000;
--terminal-dark-green: #00aa00;
--terminal-dark-amber: #cc8800;
--terminal-bg: #000000;
--terminal-bg-light: #111111;
--scan-line: rgba(0, 255, 0, 0.1);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'VT323', monospace;
background: var(--terminal-bg);
color: var(--terminal-green);
font-size: 18px;
overflow: hidden;
position: relative;
}
/* CRT Effect */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
transparent 50%,
var(--scan-line) 50%
);
background-size: 100% 4px;
animation: scan-lines 8s linear infinite;
pointer-events: none;
z-index: 1000;
}
@keyframes scan-lines {
0% { transform: translateY(0); }
100% { transform: translateY(4px); }
}
/* Phosphor Glow */
.glow {
text-shadow:
0 0 2px currentColor,
0 0 4px currentColor,
0 0 8px currentColor;
}
/* Main Container */
.terminal-container {
width: 100vw;
height: 100vh;
padding: 20px;
background: radial-gradient(ellipse at center, #001100, #000000);
display: flex;
flex-direction: column;
}
/* Terminal Header */
.terminal-header {
border: 2px solid var(--terminal-green);
padding: 10px;
margin-bottom: 10px;
position: relative;
overflow: hidden;
}
.terminal-header::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, var(--terminal-green), transparent);
animation: terminal-scan 4s linear infinite;
opacity: 0.3;
}
@keyframes terminal-scan {
0% { left: -100%; }
100% { left: 100%; }
}
.terminal-title {
font-size: 24px;
display: flex;
justify-content: space-between;
align-items: center;
}
.blink {
animation: blink-animation 1s step-start infinite;
}
@keyframes blink-animation {
50% { opacity: 0; }
}
/* Command Line Interface */
.command-line {
border: 1px solid var(--terminal-green);
padding: 10px;
margin-bottom: 10px;
background: var(--terminal-bg-light);
display: flex;
align-items: center;
font-size: 16px;
}
.prompt {
color: var(--terminal-amber);
margin-right: 10px;
}
.command-input {
flex: 1;
background: none;
border: none;
color: var(--terminal-green);
font-family: 'VT323', monospace;
font-size: 16px;
outline: none;
}
/* Control Panel */
.control-panel {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 10px;
margin-bottom: 10px;
}
.control-group {
border: 1px solid var(--terminal-dark-green);
padding: 10px;
background: var(--terminal-bg-light);
}
.control-label {
color: var(--terminal-amber);
font-size: 14px;
margin-bottom: 5px;
text-transform: uppercase;
}
.control-input {
width: 100%;
background: var(--terminal-bg);
border: 1px solid var(--terminal-green);
color: var(--terminal-green);
padding: 5px;
font-family: 'VT323', monospace;
font-size: 16px;
}
.control-button {
background: var(--terminal-bg);
border: 1px solid var(--terminal-green);
color: var(--terminal-green);
padding: 5px 10px;
cursor: pointer;
font-family: 'VT323', monospace;
font-size: 16px;
text-transform: uppercase;
transition: all 0.3s;
margin-right: 5px;
}
.control-button:hover {
background: var(--terminal-green);
color: var(--terminal-bg);
box-shadow: 0 0 10px var(--terminal-green);
}
/* Data Table */
.data-viewport {
flex: 1;
border: 2px solid var(--terminal-green);
overflow: auto;
background: var(--terminal-bg-light);
position: relative;
}
.data-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
.data-table th, .data-table td {
border: 1px solid var(--terminal-dark-green);
padding: 8px;
text-align: left;
}
.data-table th {
background: var(--terminal-bg);
color: var(--terminal-amber);
cursor: pointer;
user-select: none;
position: sticky;
top: 0;
z-index: 10;
}
.data-table th:hover {
background: var(--terminal-dark-green);
color: var(--terminal-bg);
}
.data-table tr:hover {
background: rgba(0, 255, 0, 0.1);
}
.data-table tr.selected {
background: rgba(255, 176, 0, 0.2);
color: var(--terminal-amber);
}
.checkbox-cell {
width: 30px;
text-align: center;
}
.data-checkbox {
width: 15px;
height: 15px;
appearance: none;
border: 1px solid var(--terminal-green);
background: var(--terminal-bg);
cursor: pointer;
position: relative;
}
.data-checkbox:checked::after {
content: 'X';
position: absolute;
color: var(--terminal-green);
font-size: 12px;
left: 1px;
top: -3px;
}
/* Status Bar */
.status-bar {
border: 1px solid var(--terminal-green);
padding: 10px;
margin-top: 10px;
display: flex;
justify-content: space-between;
background: var(--terminal-bg-light);
font-size: 14px;
}
.status-info {
color: var(--terminal-amber);
}
/* Pagination */
.pagination {
display: flex;
gap: 10px;
align-items: center;
}
.page-button {
background: var(--terminal-bg);
border: 1px solid var(--terminal-green);
color: var(--terminal-green);
padding: 5px 10px;
cursor: pointer;
font-family: 'VT323', monospace;
font-size: 14px;
}
.page-button:hover:not(:disabled) {
background: var(--terminal-green);
color: var(--terminal-bg);
}
.page-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.page-info {
color: var(--terminal-amber);
}
/* Loading Effect */
.loading {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
color: var(--terminal-green);
}
.loading::after {
content: '';
animation: loading-dots 1.5s infinite;
}
@keyframes loading-dots {
0% { content: ''; }
25% { content: '.'; }
50% { content: '..'; }
75% { content: '...'; }
}
/* Export Modal */
.export-modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: var(--terminal-bg);
border: 2px solid var(--terminal-green);
padding: 20px;
z-index: 2000;
display: none;
min-width: 400px;
}
.export-modal.show {
display: block;
}
.export-content {
margin: 20px 0;
padding: 10px;
background: var(--terminal-bg-light);
border: 1px solid var(--terminal-dark-green);
max-height: 300px;
overflow: auto;
white-space: pre-wrap;
font-size: 12px;
color: var(--terminal-amber);
}
/* Typing Effect */
.typing {
overflow: hidden;
white-space: nowrap;
animation: typing 3s steps(40, end);
}
@keyframes typing {
from { width: 0 }
to { width: 100% }
}
</style>
</head>
<body>
<div class="terminal-container">
<div class="terminal-header">
<div class="terminal-title glow">
<span>DATATERM v16.0 - RETRO COMPUTING DATA EXPLORER</span>
<span>[SYSTEM: ONLINE]<span class="blink"></span></span>
</div>
</div>
<div class="command-line">
<span class="prompt">DATATERM://&gt;</span>
<input type="text" class="command-input" id="commandInput" placeholder="Type 'help' for commands...">
</div>
<div class="control-panel">
<div class="control-group">
<div class="control-label">Search Query</div>
<input type="text" class="control-input" id="searchInput" placeholder="ENTER SEARCH TERM...">
</div>
<div class="control-group">
<div class="control-label">Filter By Status</div>
<select class="control-input" id="statusFilter">
<option value="">ALL RECORDS</option>
<option value="ACTIVE">ACTIVE</option>
<option value="INACTIVE">INACTIVE</option>
<option value="PENDING">PENDING</option>
<option value="ARCHIVED">ARCHIVED</option>
</select>
</div>
<div class="control-group">
<div class="control-label">Filter By Department</div>
<select class="control-input" id="deptFilter">
<option value="">ALL DEPARTMENTS</option>
<option value="ENGR">ENGINEERING</option>
<option value="MRKT">MARKETING</option>
<option value="FNCE">FINANCE</option>
<option value="OPRS">OPERATIONS</option>
</select>
</div>
<div class="control-group">
<div class="control-label">Records Per Page</div>
<select class="control-input" id="pageSizeSelect">
<option value="10">10 RECORDS</option>
<option value="25">25 RECORDS</option>
<option value="50">50 RECORDS</option>
<option value="100">100 RECORDS</option>
</select>
</div>
</div>
<div class="control-panel">
<div class="control-group">
<div class="control-label">Actions</div>
<button class="control-button" id="selectAllBtn">[SELECT ALL]</button>
<button class="control-button" id="clearAllBtn">[CLEAR ALL]</button>
<button class="control-button" id="exportBtn">[EXPORT DATA]</button>
<button class="control-button" id="refreshBtn">[REFRESH]</button>
</div>
</div>
<div class="data-viewport">
<div class="loading glow" id="loadingIndicator">LOADING DATA</div>
<table class="data-table" id="dataTable" style="display: none;">
<thead>
<tr>
<th class="checkbox-cell">
<input type="checkbox" class="data-checkbox" id="selectAllCheckbox">
</th>
<th data-sort="id">ID ↕</th>
<th data-sort="timestamp">TIMESTAMP ↕</th>
<th data-sort="user">USER ↕</th>
<th data-sort="department">DEPT ↕</th>
<th data-sort="operation">OPERATION ↕</th>
<th data-sort="status">STATUS ↕</th>
<th data-sort="size">SIZE (KB) ↕</th>
</tr>
</thead>
<tbody id="dataTableBody">
</tbody>
</table>
</div>
<div class="status-bar">
<div class="status-info">
<span id="recordCount">0 RECORDS</span> |
<span id="selectedCount">0 SELECTED</span> |
<span id="filterStatus">NO FILTERS</span>
</div>
<div class="pagination">
<button class="page-button" id="firstPageBtn">[&lt;&lt;]</button>
<button class="page-button" id="prevPageBtn">[&lt;]</button>
<span class="page-info" id="pageInfo">PAGE 1/1</span>
<button class="page-button" id="nextPageBtn">[&gt;]</button>
<button class="page-button" id="lastPageBtn">[&gt;&gt;]</button>
</div>
</div>
</div>
<div class="export-modal" id="exportModal">
<div class="terminal-header">
<div class="terminal-title glow">
<span>EXPORT DATA</span>
<button class="control-button" id="closeExportBtn">[X]</button>
</div>
</div>
<div class="control-group">
<div class="control-label">Export Format</div>
<select class="control-input" id="exportFormat">
<option value="csv">CSV FORMAT</option>
<option value="json">JSON FORMAT</option>
<option value="txt">TEXT FORMAT</option>
</select>
</div>
<div class="export-content" id="exportContent"></div>
<button class="control-button" id="downloadBtn">[DOWNLOAD FILE]</button>
<button class="control-button" id="copyBtn">[COPY TO CLIPBOARD]</button>
</div>
<script>
// Generate sample data
const departments = ['ENGR', 'MRKT', 'FNCE', 'OPRS'];
const operations = ['CREATE', 'UPDATE', 'DELETE', 'READ', 'BACKUP', 'RESTORE', 'SYNC', 'VERIFY'];
const statuses = ['ACTIVE', 'INACTIVE', 'PENDING', 'ARCHIVED'];
const users = ['USER_001', 'USER_002', 'USER_003', 'USER_004', 'USER_005', 'ADMIN_01', 'ADMIN_02', 'SYS_USER'];
let allData = [];
let filteredData = [];
let currentPage = 1;
let pageSize = 10;
let sortColumn = 'id';
let sortDirection = 'asc';
let selectedRows = new Set();
// Generate data
function generateData() {
allData = [];
for (let i = 1; i <= 500; i++) {
const timestamp = new Date(Date.now() - Math.random() * 30 * 24 * 60 * 60 * 1000);
allData.push({
id: `REC_${String(i).padStart(5, '0')}`,
timestamp: timestamp.toISOString().replace('T', ' ').substr(0, 19),
user: users[Math.floor(Math.random() * users.length)],
department: departments[Math.floor(Math.random() * departments.length)],
operation: operations[Math.floor(Math.random() * operations.length)],
status: statuses[Math.floor(Math.random() * statuses.length)],
size: Math.floor(Math.random() * 1000) + 1
});
}
filteredData = [...allData];
}
// Initialize
function init() {
generateData();
setTimeout(() => {
document.getElementById('loadingIndicator').style.display = 'none';
document.getElementById('dataTable').style.display = 'table';
renderTable();
updateStatus();
}, 1500);
// Event listeners
document.getElementById('searchInput').addEventListener('input', applyFilters);
document.getElementById('statusFilter').addEventListener('change', applyFilters);
document.getElementById('deptFilter').addEventListener('change', applyFilters);
document.getElementById('pageSizeSelect').addEventListener('change', (e) => {
pageSize = parseInt(e.target.value);
currentPage = 1;
renderTable();
});
// Command input
document.getElementById('commandInput').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
processCommand(e.target.value);
e.target.value = '';
}
});
// Sorting
document.querySelectorAll('[data-sort]').forEach(th => {
th.addEventListener('click', () => {
const column = th.dataset.sort;
if (sortColumn === column) {
sortDirection = sortDirection === 'asc' ? 'desc' : 'asc';
} else {
sortColumn = column;
sortDirection = 'asc';
}
sortData();
renderTable();
});
});
// Selection
document.getElementById('selectAllCheckbox').addEventListener('change', (e) => {
const checkboxes = document.querySelectorAll('.row-checkbox');
checkboxes.forEach(cb => {
cb.checked = e.target.checked;
const row = cb.closest('tr');
const id = row.dataset.id;
if (e.target.checked) {
selectedRows.add(id);
row.classList.add('selected');
} else {
selectedRows.delete(id);
row.classList.remove('selected');
}
});
updateStatus();
});
// Buttons
document.getElementById('selectAllBtn').addEventListener('click', () => {
filteredData.forEach(item => selectedRows.add(item.id));
renderTable();
updateStatus();
});
document.getElementById('clearAllBtn').addEventListener('click', () => {
selectedRows.clear();
document.getElementById('selectAllCheckbox').checked = false;
renderTable();
updateStatus();
});
document.getElementById('exportBtn').addEventListener('click', showExportModal);
document.getElementById('refreshBtn').addEventListener('click', () => {
generateData();
applyFilters();
});
// Pagination
document.getElementById('firstPageBtn').addEventListener('click', () => {
currentPage = 1;
renderTable();
});
document.getElementById('prevPageBtn').addEventListener('click', () => {
if (currentPage > 1) {
currentPage--;
renderTable();
}
});
document.getElementById('nextPageBtn').addEventListener('click', () => {
if (currentPage < getTotalPages()) {
currentPage++;
renderTable();
}
});
document.getElementById('lastPageBtn').addEventListener('click', () => {
currentPage = getTotalPages();
renderTable();
});
// Export modal
document.getElementById('closeExportBtn').addEventListener('click', hideExportModal);
document.getElementById('exportFormat').addEventListener('change', updateExportPreview);
document.getElementById('downloadBtn').addEventListener('click', downloadExport);
document.getElementById('copyBtn').addEventListener('click', copyToClipboard);
}
// Process commands
function processCommand(command) {
const cmd = command.toLowerCase().trim();
switch (cmd) {
case 'help':
alert('AVAILABLE COMMANDS:\n\n' +
'HELP - Show this menu\n' +
'CLEAR - Clear all filters\n' +
'SELECT ALL - Select all records\n' +
'EXPORT - Export selected data\n' +
'REFRESH - Reload data\n' +
'SORT [COLUMN] - Sort by column\n' +
'FILTER [COLUMN] [VALUE] - Apply filter');
break;
case 'clear':
document.getElementById('searchInput').value = '';
document.getElementById('statusFilter').value = '';
document.getElementById('deptFilter').value = '';
applyFilters();
break;
case 'select all':
document.getElementById('selectAllBtn').click();
break;
case 'export':
document.getElementById('exportBtn').click();
break;
case 'refresh':
document.getElementById('refreshBtn').click();
break;
default:
if (cmd.startsWith('sort ')) {
const column = cmd.substr(5);
const th = document.querySelector(`[data-sort="${column}"]`);
if (th) th.click();
} else if (cmd.startsWith('filter ')) {
const parts = cmd.substr(7).split(' ');
if (parts.length >= 2) {
const [column, ...valueParts] = parts;
const value = valueParts.join(' ');
if (column === 'status') {
document.getElementById('statusFilter').value = value.toUpperCase();
} else if (column === 'department' || column === 'dept') {
document.getElementById('deptFilter').value = value.toUpperCase();
} else {
document.getElementById('searchInput').value = value;
}
applyFilters();
}
}
}
}
// Apply filters
function applyFilters() {
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
const statusFilter = document.getElementById('statusFilter').value;
const deptFilter = document.getElementById('deptFilter').value;
filteredData = allData.filter(item => {
const matchesSearch = !searchTerm ||
Object.values(item).some(val =>
String(val).toLowerCase().includes(searchTerm)
);
const matchesStatus = !statusFilter || item.status === statusFilter;
const matchesDept = !deptFilter || item.department === deptFilter;
return matchesSearch && matchesStatus && matchesDept;
});
currentPage = 1;
sortData();
renderTable();
updateStatus();
}
// Sort data
function sortData() {
filteredData.sort((a, b) => {
let aVal = a[sortColumn];
let bVal = b[sortColumn];
if (sortColumn === 'size') {
aVal = parseInt(aVal);
bVal = parseInt(bVal);
}
if (aVal < bVal) return sortDirection === 'asc' ? -1 : 1;
if (aVal > bVal) return sortDirection === 'asc' ? 1 : -1;
return 0;
});
}
// Get total pages
function getTotalPages() {
return Math.ceil(filteredData.length / pageSize);
}
// Render table
function renderTable() {
const tbody = document.getElementById('dataTableBody');
tbody.innerHTML = '';
const start = (currentPage - 1) * pageSize;
const end = start + pageSize;
const pageData = filteredData.slice(start, end);
pageData.forEach(item => {
const row = document.createElement('tr');
row.dataset.id = item.id;
if (selectedRows.has(item.id)) {
row.classList.add('selected');
}
row.innerHTML = `
<td class="checkbox-cell">
<input type="checkbox" class="data-checkbox row-checkbox"
${selectedRows.has(item.id) ? 'checked' : ''}>
</td>
<td>${item.id}</td>
<td>${item.timestamp}</td>
<td>${item.user}</td>
<td>${item.department}</td>
<td>${item.operation}</td>
<td>${item.status}</td>
<td>${item.size}</td>
`;
const checkbox = row.querySelector('.row-checkbox');
checkbox.addEventListener('change', (e) => {
if (e.target.checked) {
selectedRows.add(item.id);
row.classList.add('selected');
} else {
selectedRows.delete(item.id);
row.classList.remove('selected');
}
updateStatus();
});
tbody.appendChild(row);
});
// Update pagination
document.getElementById('pageInfo').textContent = `PAGE ${currentPage}/${getTotalPages() || 1}`;
document.getElementById('firstPageBtn').disabled = currentPage === 1;
document.getElementById('prevPageBtn').disabled = currentPage === 1;
document.getElementById('nextPageBtn').disabled = currentPage >= getTotalPages();
document.getElementById('lastPageBtn').disabled = currentPage >= getTotalPages();
}
// Update status
function updateStatus() {
document.getElementById('recordCount').textContent = `${filteredData.length} RECORDS`;
document.getElementById('selectedCount').textContent = `${selectedRows.size} SELECTED`;
const filters = [];
if (document.getElementById('searchInput').value) filters.push('SEARCH');
if (document.getElementById('statusFilter').value) filters.push('STATUS');
if (document.getElementById('deptFilter').value) filters.push('DEPT');
document.getElementById('filterStatus').textContent =
filters.length ? `FILTERS: ${filters.join(', ')}` : 'NO FILTERS';
}
// Export functions
function showExportModal() {
document.getElementById('exportModal').classList.add('show');
updateExportPreview();
}
function hideExportModal() {
document.getElementById('exportModal').classList.remove('show');
}
function updateExportPreview() {
const format = document.getElementById('exportFormat').value;
const dataToExport = selectedRows.size > 0
? filteredData.filter(item => selectedRows.has(item.id))
: filteredData;
let content = '';
if (format === 'csv') {
content = 'ID,TIMESTAMP,USER,DEPARTMENT,OPERATION,STATUS,SIZE_KB\n';
dataToExport.forEach(item => {
content += `${item.id},${item.timestamp},${item.user},${item.department},${item.operation},${item.status},${item.size}\n`;
});
} else if (format === 'json') {
content = JSON.stringify(dataToExport, null, 2);
} else if (format === 'txt') {
dataToExport.forEach(item => {
content += `========================================\n`;
content += `ID: ${item.id}\n`;
content += `TIMESTAMP: ${item.timestamp}\n`;
content += `USER: ${item.user}\n`;
content += `DEPARTMENT: ${item.department}\n`;
content += `OPERATION: ${item.operation}\n`;
content += `STATUS: ${item.status}\n`;
content += `SIZE: ${item.size} KB\n`;
});
}
document.getElementById('exportContent').textContent = content;
}
function downloadExport() {
const format = document.getElementById('exportFormat').value;
const content = document.getElementById('exportContent').textContent;
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `dataterm_export_${Date.now()}.${format}`;
a.click();
URL.revokeObjectURL(url);
}
function copyToClipboard() {
const content = document.getElementById('exportContent').textContent;
navigator.clipboard.writeText(content).then(() => {
const btn = document.getElementById('copyBtn');
const originalText = btn.textContent;
btn.textContent = '[COPIED!]';
setTimeout(() => {
btn.textContent = originalText;
}, 2000);
});
}
// Initialize on load
window.addEventListener('load', init);
</script>
</body>
</html>