/** * Data Table Component with Selection & Inline Editing * For dashboard-like interfaces */ const { useState, useEffect, useMemo } = window.PreactLib || {}; export function DashboardTable({ data = [], columns = [], onSelectionChange, onRowUpdate, onRowDelete, actions = [], className = '' }) { const html = window.html; const [selectedIds, setSelectedIds] = useState(new Set()); const [editingId, setEditingId] = useState(null); const [editValue, setEditValue] = useState(''); const allSelected = data.length > 0 && selectedIds.size === data.length; const someSelected = selectedIds.size > 0 && selectedIds.size < data.length; const toggleSelectAll = () => { if (allSelected) { setSelectedIds(new Set()); } else { setSelectedIds(new Set(data.map(row => row.id))); } }; const toggleSelect = (id) => { const newSelected = new Set(selectedIds); if (newSelected.has(id)) { newSelected.delete(id); } else { newSelected.add(id); } setSelectedIds(newSelected); }; const startEditing = (row, columnKey) => { setEditingId(row.id); setEditValue(row[columnKey]); }; const saveEdit = (columnKey) => { if (onRowUpdate) { onRowUpdate(editingId, { [columnKey]: editValue }); } setEditingId(null); }; const cancelEdit = () => { setEditingId(null); setEditValue(''); }; useEffect(() => { if (onSelectionChange) { onSelectionChange(Array.from(selectedIds)); } }, [selectedIds]); return html`
${columns.map(col => html` `)} ${actions.length > 0 ? html`` : ''} ${data.length === 0 ? html` ` : data.map(row => html` ${columns.map(col => html` `)} ${actions.length > 0 ? html` ` : ''} `)}
${col.header}Actions
No data available
toggleSelect(row.id)} /> ${editingId === row.id && col.editable ? html`
setEditValue(e.target.value)} onBlur=${() => saveEdit(col.key)} onKeyDown=${(e) => { if (e.key === 'Enter') saveEdit(col.key); if (e.key === 'Escape') cancelEdit(); }} autofocus />
` : html`
col.editable && startEditing(row, col.key)} > ${col.render ? col.render(row[col.key], row) : row[col.key]} ${col.editable ? html`` : ''}
`}
${actions.map(action => { // Skip hidden actions if (action.hidden && action.hidden(row)) { return null; } return html` `; })}
`; } // === Filter Tabs Component === export function FilterTabs({ filters = [], activeFilter = 'all', onChange, className = '' }) { const html = window.html; return html` `; } // === Bulk Actions Bar === export function BulkActionsBar({ selectedCount = 0, actions = [], onClearSelection, className = '' }) { const html = window.html; if (selectedCount === 0) return null; return html`
${selectedCount} item${selectedCount > 1 ? 's' : ''} selected
${actions.map(action => html` `)}
`; } export default DashboardTable;