minimew commited on
Commit
74bb6a2
·
verified ·
1 Parent(s): 93a9858

Upload src/app/giao_dien/text_to_sql_dashboard/code.html with huggingface_hub

Browse files
src/app/giao_dien/text_to_sql_dashboard/code.html CHANGED
@@ -234,10 +234,31 @@
234
  </div>
235
  <!-- Sample Mode Content -->
236
  <div class="space-y-4" id="source-sample">
 
237
  <h3 class="font-label-caps text-label-caps text-secondary uppercase" id="schema-title">Active Schema: ...</h3>
238
- <div class="bg-code-bg border border-border-subtle p-4 rounded font-code-block text-code-block text-on-surface-variant overflow-x-auto">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  <pre id="schema-block">Loading schema...</pre>
240
  </div>
 
241
  </div>
242
  <!-- Upload Mode Content (Hidden by default) -->
243
  <div class="hidden space-y-4" id="source-upload">
@@ -455,6 +476,7 @@
455
  }
456
 
457
  toggleDataSource(meta.mode === 'uploaded' ? 'upload' : 'sample');
 
458
  loadModels();
459
  }
460
 
@@ -572,6 +594,62 @@
572
  }
573
  });
574
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
575
  // ---- Banners (validator block / execution error) ----
576
  function renderBanners(data) {
577
  const container = document.getElementById('banners');
 
234
  </div>
235
  <!-- Sample Mode Content -->
236
  <div class="space-y-4" id="source-sample">
237
+ <div class="flex items-center justify-between">
238
  <h3 class="font-label-caps text-label-caps text-secondary uppercase" id="schema-title">Active Schema: ...</h3>
239
+ <select class="px-2 py-1 border border-border-subtle rounded text-status-badge font-status-badge bg-white text-on-surface" id="sample-table-select" title="Select table to preview"></select>
240
+ </div>
241
+ <!-- Data preview table (same style as upload preview) -->
242
+ <div id="sample-preview-wrap">
243
+ <div class="overflow-x-auto rounded border border-border-subtle">
244
+ <table class="w-full text-left font-body-sm text-body-sm" id="sample-preview-table">
245
+ <thead class="bg-surface-container-high border-b border-border-subtle font-code-block uppercase text-[11px]"><tr></tr></thead>
246
+ <tbody class="divide-y divide-border-subtle bg-white"></tbody>
247
+ </table>
248
+ </div>
249
+ <div class="flex items-center justify-between mt-3">
250
+ <button class="px-3 py-1 border border-border-subtle rounded text-body-sm font-label-caps text-label-caps uppercase bg-white hover:bg-surface-container-low disabled:opacity-40 disabled:cursor-not-allowed" disabled id="sample-prev-btn">‹ Previous</button>
251
+ <span class="text-body-sm text-secondary" id="sample-page-label">Loading...</span>
252
+ <button class="px-3 py-1 border border-border-subtle rounded text-body-sm font-label-caps text-label-caps uppercase bg-white hover:bg-surface-container-low disabled:opacity-40 disabled:cursor-not-allowed" disabled id="sample-next-btn">Next ›</button>
253
+ </div>
254
+ </div>
255
+ <!-- Schema string (collapsible) -->
256
+ <details class="mt-1">
257
+ <summary class="font-label-caps text-label-caps text-secondary uppercase cursor-pointer select-none hover:text-primary transition-colors text-[11px]">View schema string</summary>
258
+ <div class="bg-code-bg border border-border-subtle p-4 rounded font-code-block text-code-block text-on-surface-variant overflow-x-auto mt-2">
259
  <pre id="schema-block">Loading schema...</pre>
260
  </div>
261
+ </details>
262
  </div>
263
  <!-- Upload Mode Content (Hidden by default) -->
264
  <div class="hidden space-y-4" id="source-upload">
 
476
  }
477
 
478
  toggleDataSource(meta.mode === 'uploaded' ? 'upload' : 'sample');
479
+ if (meta.mode !== 'uploaded') loadSamplePreview();
480
  loadModels();
481
  }
482
 
 
594
  }
595
  });
596
 
597
+ // ---- Sample database table preview ----
598
+ let samplePreviewState = { columns: [], rows: [], rowCount: 0, tableNames: [], activeTable: '', page: 0 };
599
+
600
+ async function loadSamplePreview(table) {
601
+ try {
602
+ const url = `${API_BASE}/api/preview` + (table ? `?table=${encodeURIComponent(table)}` : '');
603
+ const res = await fetch(url);
604
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
605
+ const data = await res.json();
606
+ samplePreviewState = { columns: data.columns, rows: data.rows, rowCount: data.row_count,
607
+ truncated: data.truncated, tableNames: data.table_names, activeTable: data.active_table, page: 0 };
608
+
609
+ const sel = document.getElementById('sample-table-select');
610
+ sel.innerHTML = samplePreviewState.tableNames.map(t =>
611
+ `<option value="${t}" ${t === data.active_table ? 'selected' : ''}>${t}</option>`
612
+ ).join('');
613
+
614
+ renderSamplePreviewPage();
615
+ } catch (err) {
616
+ console.error('Failed to load sample preview:', err);
617
+ }
618
+ }
619
+
620
+ function renderSamplePreviewPage() {
621
+ const { columns, rows, rowCount, page } = samplePreviewState;
622
+ const totalPages = Math.max(1, Math.ceil(rows.length / PREVIEW_PAGE_SIZE));
623
+ const start = page * PREVIEW_PAGE_SIZE;
624
+ const pageRows = rows.slice(start, start + PREVIEW_PAGE_SIZE);
625
+
626
+ const thead = document.querySelector('#sample-preview-table thead tr');
627
+ thead.innerHTML = columns.map(c => `<th class="px-4 py-2 border-r border-border-subtle">${escapeHtml(String(c))}</th>`).join('');
628
+
629
+ const tbody = document.querySelector('#sample-preview-table tbody');
630
+ tbody.innerHTML = pageRows.map(row =>
631
+ `<tr class="hover:bg-surface-container-low">${row.map(v =>
632
+ `<td class="px-4 py-2 border-r border-border-subtle">${escapeHtml(v === null ? '' : String(v))}</td>`
633
+ ).join('')}</tr>`
634
+ ).join('');
635
+
636
+ document.getElementById('sample-page-label').textContent =
637
+ `Rows ${start + 1}–${start + pageRows.length} of ${rowCount} total (page ${page + 1} / ${totalPages})`;
638
+ document.getElementById('sample-prev-btn').disabled = page <= 0;
639
+ document.getElementById('sample-next-btn').disabled = page >= totalPages - 1;
640
+ }
641
+
642
+ document.getElementById('sample-prev-btn').addEventListener('click', () => {
643
+ if (samplePreviewState.page > 0) { samplePreviewState.page -= 1; renderSamplePreviewPage(); }
644
+ });
645
+ document.getElementById('sample-next-btn').addEventListener('click', () => {
646
+ const totalPages = Math.max(1, Math.ceil(samplePreviewState.rows.length / PREVIEW_PAGE_SIZE));
647
+ if (samplePreviewState.page < totalPages - 1) { samplePreviewState.page += 1; renderSamplePreviewPage(); }
648
+ });
649
+ document.getElementById('sample-table-select').addEventListener('change', (e) => {
650
+ loadSamplePreview(e.target.value);
651
+ });
652
+
653
  // ---- Banners (validator block / execution error) ----
654
  function renderBanners(data) {
655
  const container = document.getElementById('banners');