|
|
class CustomDataTable extends HTMLElement { |
|
|
connectedCallback() { |
|
|
this.attachShadow({ mode: 'open' }); |
|
|
this.shadowRoot.innerHTML = ` |
|
|
<style> |
|
|
.table-container { |
|
|
overflow-x: auto; |
|
|
} |
|
|
|
|
|
.terminal-table { |
|
|
width: 100%; |
|
|
border-collapse: collapse; |
|
|
font-size: 0.75rem; |
|
|
} |
|
|
|
|
|
.terminal-table th { |
|
|
background: rgba(15, 17, 21, 0.9); |
|
|
border-bottom: 1px solid #4a5568; |
|
|
padding: 0.75rem; |
|
|
text-align: left; |
|
|
font-family: 'Chakra Petch', monospace; |
|
|
text-transform: uppercase; |
|
|
letter-spacing: 0.1em; |
|
|
color: #4a5568; |
|
|
font-weight: 600; |
|
|
} |
|
|
|
|
|
.terminal-table td { |
|
|
padding: 0.75rem; |
|
|
border-bottom: 1px solid rgba(74, 85, 104, 0.3); |
|
|
} |
|
|
|
|
|
.terminal-table tr:hover { |
|
|
background: rgba(255, 159, 28, 0.05); |
|
|
} |
|
|
|
|
|
.terminal-table tr:last-child td { |
|
|
border-bottom: none; |
|
|
} |
|
|
|
|
|
.status-badge { |
|
|
display: inline-block; |
|
|
padding: 0.25rem 0.5rem; |
|
|
font-size: 0.625rem; |
|
|
text-transform: uppercase; |
|
|
letter-spacing: 0.1em; |
|
|
} |
|
|
|
|
|
.status-success { |
|
|
background: rgba(5, 150, 105, 0.1); |
|
|
color: #059669; |
|
|
border: 1px solid rgba(5, 150, 105, 0.3); |
|
|
} |
|
|
|
|
|
.status-warning { |
|
|
background: rgba(255, 159, 28, 0.1); |
|
|
color: #ff9f1c; |
|
|
border: 1px solid rgba(255, 159, 28, 0.3); |
|
|
} |
|
|
|
|
|
.status-error { |
|
|
background: rgba(220, 38, 38, 0.1); |
|
|
color: #dc2626; |
|
|
border: 1px solid rgba(220, 38, 38, 0.3); |
|
|
} |
|
|
|
|
|
.table-actions { |
|
|
display: flex; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.action-btn { |
|
|
background: transparent; |
|
|
border: 1px solid #4a5568; |
|
|
color: #4a5568; |
|
|
padding: 0.25rem 0.5rem; |
|
|
font-size: 0.75rem; |
|
|
cursor: pointer; |
|
|
transition: all 0.3s ease; |
|
|
} |
|
|
|
|
|
.action-btn:hover { |
|
|
border-color: #ff9f1c; |
|
|
color: #ff9f1c; |
|
|
} |
|
|
|
|
|
.pagination { |
|
|
display: flex; |
|
|
justify-content: space-between; |
|
|
align-items: center; |
|
|
padding: 1rem; |
|
|
border-top: 1px solid #4a5568; |
|
|
background: rgba(15, 17, 21, 0.5); |
|
|
} |
|
|
|
|
|
.pagination-controls { |
|
|
display: flex; |
|
|
gap: 0.5rem; |
|
|
} |
|
|
|
|
|
.page-info { |
|
|
font-size: 0.75rem; |
|
|
color: #4a5568; |
|
|
} |
|
|
|
|
|
@media (max-width: 768px) { |
|
|
.terminal-table { |
|
|
font-size: 0.625rem; |
|
|
} |
|
|
|
|
|
.action-btn { |
|
|
font-size: 0.625rem; |
|
|
padding: 0.125rem 0.375rem; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
<div class="table-container"> |
|
|
<table class="terminal-table"> |
|
|
<thead> |
|
|
<tr> |
|
|
<th>ID</th> |
|
|
<th>Timestamp</th> |
|
|
<th>Event Type</th> |
|
|
<th>Source</th> |
|
|
<th>Status</th> |
|
|
<th>Actions</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody> |
|
|
<tr> |
|
|
<td class="text-[#ff9f1c]">LOG-8472</td> |
|
|
<td>23:47:15 AKST</td> |
|
|
<td>THREAT DETECTED</td> |
|
|
<td>PERIMETER-ALPHA</td> |
|
|
<td> |
|
|
<span class="status-badge status-error">CRITICAL</span> |
|
|
</td> |
|
|
<td> |
|
|
<div class="table-actions"> |
|
|
<button class="action-btn" data-action="view"> |
|
|
<i data-feather="eye"></i> |
|
|
</button> |
|
|
<button class="action-btn" data-action="resolve"> |
|
|
<i data-feather="check-circle"></i> |
|
|
</button> |
|
|
</div> |
|
|
</td> |
|
|
</tr> |
|
|
<tr> |
|
|
<td class="text-[#ff9f1c]">LOG-8471</td> |
|
|
<td>23:32:08 AKST</td> |
|
|
<td>SYSTEM SCAN</td> |
|
|
<td>CORE-FURNACE</td> |
|
|
<td> |
|
|
<span class="status-badge status-success">NOMINAL</span> |
|
|
</td> |
|
|
<td> |
|
|
<div class="table-actions"> |
|
|
<button class="action-btn" data-action="view"> |
|
|
<i data-feather="eye"></i> |
|
|
</button> |
|
|
</td> |
|
|
</tr> |
|
|
<tr> |
|
|
<td class="text-[#ff9f1c]">LOG-8470</td> |
|
|
<td>23:15:42 AKST</td> |
|
|
<td>BOT UPDATE</td> |
|
|
<td>ALPHA-WOLF</td> |
|
|
<td> |
|
|
<span class="status-badge status-warning">WARNING</span> |
|
|
</td> |
|
|
<td> |
|
|
<div class="table-actions"> |
|
|
<button class="action-btn" data-action="view"> |
|
|
<i data-feather="eye"></i> |
|
|
</button> |
|
|
<button class="action-btn" data-action="resolve"> |
|
|
<i data-feather="check-circle"></i> |
|
|
</button> |
|
|
</div> |
|
|
</td> |
|
|
</tr> |
|
|
<tr> |
|
|
<td class="text-[#ff9f1c]">LOG-8469</td> |
|
|
<td>22:58:27 AKST</td> |
|
|
<td>POWER FLUCTUATION</td> |
|
|
<td>GRID-BETA</td> |
|
|
<td> |
|
|
<span class="status-badge status-success">RESOLVED</span> |
|
|
</td> |
|
|
<td> |
|
|
<div class="table-actions"> |
|
|
<button class="action-btn" data-action="view"> |
|
|
<i data-feather="eye"></i> |
|
|
</button> |
|
|
</div> |
|
|
</td> |
|
|
</tr> |
|
|
</tbody> |
|
|
</table> |
|
|
|
|
|
<div class="pagination"> |
|
|
<div class="page-info"> |
|
|
SHOWING 4 OF 1287 ENTRIES |
|
|
</div> |
|
|
|
|
|
<div class="pagination-controls"> |
|
|
<button class="action-btn"> |
|
|
<i data-feather="chevron-left"></i> |
|
|
</button> |
|
|
<button class="action-btn active"> |
|
|
1 |
|
|
</button> |
|
|
<button class="action-btn"> |
|
|
2 |
|
|
</button> |
|
|
<button class="action-btn"> |
|
|
3 |
|
|
</button> |
|
|
<span style="color: #4a5568; padding: 0 0.25rem;">...</button> |
|
|
<button class="action-btn"> |
|
|
42 |
|
|
</button> |
|
|
<button class="action-btn"> |
|
|
<i data-feather="chevron-right"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
const icons = this.shadowRoot.querySelectorAll('[data-feather]'); |
|
|
icons.forEach(icon => { |
|
|
feather.replace(icon); |
|
|
}); |
|
|
|
|
|
const actionButtons = this.shadowRoot.querySelectorAll('.action-btn'); |
|
|
actionButtons.forEach(button => { |
|
|
button.addEventListener('click', (e) => { |
|
|
const action = button.getAttribute('data-action'); |
|
|
this.handleTableAction(action, button.closest('tr')); |
|
|
}); |
|
|
}); |
|
|
}, 100); |
|
|
} |
|
|
|
|
|
handleTableAction(action, row) { |
|
|
const rowId = row.querySelector('td:first-child').textContent; |
|
|
|
|
|
const modal = document.createElement('div'); |
|
|
modal.style.cssText = ` |
|
|
position: fixed; |
|
|
top: 0; |
|
|
left: 0; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
background: rgba(0, 0, 0, 0.9); |
|
|
color: #ff9f1c; |
|
|
font-family: 'JetBrains Mono', monospace; |
|
|
padding: 2rem; |
|
|
z-index: 1000; |
|
|
overflow-y: auto; |
|
|
`; |
|
|
|
|
|
modal.innerHTML = ` |
|
|
<div style="border: 1px solid #4a5568; padding: 1rem;"> |
|
|
<div style="display: flex; justify-content: space-between; margin-bottom: 1rem;"> |
|
|
<h3 style="font-family: 'Chakra Petch', monospace; text-transform: uppercase; letter-spacing: 0.1em;">ACTION: ${action.toUpperCase()} - ${rowId}</h3> |
|
|
<button onclick="this.parentElement.parentElement.parentElement.remove()" style="background: transparent; border: 1px solid #4a5568; color: #4a5568; padding: 0.25rem 0.5rem; cursor: pointer;">CLOSE</button> |
|
|
</div> |
|
|
<div style="background: #0a0c10; border: 1px solid #4a5568; padding: 1rem; font-size: 0.875rem;"> |
|
|
> Executing ${action} on ${rowId}...<br> |
|
|
> Processing request...<br> |
|
|
> Action completed successfully<br> |
|
|
> Systems updated<br> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
document.body.appendChild(modal); |
|
|
} |
|
|
} |
|
|
|
|
|
customElements.define('custom-data-table', CustomDataTable); |