ai-research-survey

Systematic scan of agentic development research. What's signal, what's noise.
git clone https://git.shiptheloop.com/ai-research-survey.git
Log | Files | Refs

table.ts (1855B)


      1 export interface Column<T> {
      2   key: string;
      3   label: string;
      4   render: (item: T) => string;
      5   sortValue?: (item: T) => number | string;
      6 }
      7 
      8 export function renderSortableTable<T>(
      9   items: T[],
     10   columns: Column<T>[],
     11   onRowClick: (item: T) => void,
     12   sortKey = 'score',
     13   sortAsc = false,
     14 ): HTMLElement {
     15   const wrap = document.createElement('div');
     16   wrap.className = 'table-wrap';
     17 
     18   let currentSort = sortKey;
     19   let asc = sortAsc;
     20 
     21   function render() {
     22     const sorted = [...items];
     23     const col = columns.find(c => c.key === currentSort);
     24     if (col?.sortValue) {
     25       sorted.sort((a, b) => {
     26         const va = col.sortValue!(a);
     27         const vb = col.sortValue!(b);
     28         if (typeof va === 'number' && typeof vb === 'number') return asc ? va - vb : vb - va;
     29         return asc ? String(va).localeCompare(String(vb)) : String(vb).localeCompare(String(va));
     30       });
     31     }
     32 
     33     wrap.innerHTML = `<table>
     34       <thead><tr>${columns.map(c =>
     35         `<th data-key="${c.key}" class="${c.key === currentSort ? 'sorted' + (asc ? ' asc' : '') : ''}">${c.label}</th>`
     36       ).join('')}</tr></thead>
     37       <tbody>${sorted.map((item, i) =>
     38         `<tr data-idx="${i}">${columns.map(c => `<td${c.key === 'score' ? ' class="score"' : ''}>${c.render(item)}</td>`).join('')}</tr>`
     39       ).join('')}</tbody>
     40     </table>`;
     41 
     42     wrap.querySelectorAll('thead th').forEach(th => {
     43       th.addEventListener('click', () => {
     44         const key = (th as HTMLElement).dataset.key!;
     45         if (currentSort === key) asc = !asc;
     46         else { currentSort = key; asc = false; }
     47         render();
     48       });
     49     });
     50 
     51     wrap.querySelectorAll('tbody tr').forEach(tr => {
     52       tr.addEventListener('click', () => {
     53         const idx = parseInt((tr as HTMLElement).dataset.idx!);
     54         onRowClick(sorted[idx]);
     55       });
     56     });
     57   }
     58 
     59   render();
     60   return wrap;
     61 }

Impressum · Datenschutz