omniloop-ai / components /data-table.js
00Boobs00's picture
Review revise and update with refactoring, refinement and optimization expanding this out to at least 4 times its origional size and magnitude.
3bcb678 verified
class DataTable extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.data = [];
this.sortColumn = null;
this.sortDirection = 'asc';
}
connectedCallback() {
this.generateData();
this.render();
this.attachEvents();
}
generateData() {
const operations = [
'Inference Request', 'Model Update', 'Data Preprocessing', 'API Call',
'Cache Miss', 'Authentication', 'Validation Check', 'Batch Processing'
];
const statuses = ['success', 'pending', 'error'];
for (let i = 0; i < 20; i++) {
this.data.push({
id: `OP-${10000 + i}`,
operation: operations[Math.floor(Math.random() * operations.length)],
timestamp: new Date(Date.now() - Math.random() * 3600000).toISOString(),
duration: Math.floor(Math.random() * 500 + 10),
status: statuses[Math.floor(Math.random() * statuses.length)]
});
}
}
sort(column) {
if (this.sortColumn === column) {
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
} else {
this.sortColumn = column;
this.sortDirection = 'asc';
}
this.data.sort((a, b) => {
let valA = a[column];
let valB = b[column];
if (typeof valA === 'string') valA = valA.toLowerCase();
if (typeof valB === 'string') valB = valB.toLowerCase();
if (valA < valB) return this.sortDirection === 'asc' ? -1 : 1;
if (valA > valB) return this.sortDirection === 'asc' ? 1 : -1;
return 0;
});
this.render();
}
getStatusBadge(status) {
const styles = {
success: 'bg-green-900/50 text-green-400',
pending: 'bg-yellow-900/50 text-yellow-400',
error: 'bg-red-900/50 text-red-400'
};
return `<span class="px-2 py-1 rounded text-xs ${styles[status]}">${status.charAt(0).toUpperCase() + status.slice(1)}</span>`;
}
render() {
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
table {
width: 100%;
border-collapse: collapse;
}
th {
text-align: left;
padding: 12px;
border-bottom: 1px solid #334155;
color: #94a3b8;
font-size: 12px;
text-transform: uppercase;
cursor: pointer;
user-select: none;
}
th:hover {
color: #e2e8f0;
background: rgba(255,255,255,0.02);
}
td {
padding: 12px;
border-bottom: 1px solid #1e293b;
font-size: 14px;
}
tr:hover td {
background: rgba(255,255,255,0.02);
}
.sort-icon {
margin-left: 4px;
opacity: 0.5;
}
</style>
<div style="overflow-x: auto;">
<table>
<thead>
<tr>
<th onclick="this.getRootNode().host.sort('id')">
ID ${this.sortColumn === 'id' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
</th>
<th onclick="this.getRootNode().host.sort('operation')">
Operation ${this.sortColumn === 'operation' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
</th>
<th onclick="this.getRootNode().host.sort('timestamp')">
Timestamp ${this.sortColumn === 'timestamp' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
</th>
<th onclick="this.getRootNode().host.sort('duration')">
Duration ${this.sortColumn === 'duration' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
</th>
<th onclick="this.getRootNode().host.sort('status')">
Status ${this.sortColumn === 'status' ? (this.sortDirection === 'asc' ? '↑' : '↓') : ''}
</th>
</tr>
</thead>
<tbody>
${this.data.map(row => `
<tr>
<td class="font-mono text-slate-400">${row.id}</td>
<td class="text-white">${row.operation}</td>
<td class="text-slate-400">${new Date(row.timestamp).toLocaleString()}</td>
<td class="text-slate-300">${row.duration}ms</td>
<td>${this.getStatusBadge(row.status)}</td>
</tr>
`).join('')}
</tbody>
</table>
</div>
`;
}
attachEvents() {
// Add new data periodically
setInterval(() => {
const operations = ['Inference Request', 'Model Update', 'Data Preprocessing', 'API Call'];
const statuses = ['success', 'pending', 'error'];
this.data.unshift({
id: `OP-${10000 + this.data.length}`,
operation: operations[Math.floor(Math.random() * operations.length)],
timestamp: new Date().toISOString(),
duration: Math.floor(Math.random() * 500 + 10),
status: statuses[Math.floor(Math.random() * statuses.length)]
});
if (this.data.length > 50) {
this.data.pop();
}
this.render();
}, 3000);
}
}
customElements.define('data-table', DataTable);