Deadman922 commited on
Commit
5fb9eee
·
verified ·
1 Parent(s): 435b5ba

Upload index.html

Browse files
Files changed (1) hide show
  1. static/index.html +162 -19
static/index.html CHANGED
@@ -1449,36 +1449,42 @@ async function uploadDatabase() {
1449
  customDbFilename = data.filename;
1450
  firstCustomTable = data.tables[0]?.table_name || 'table';
1451
 
1452
- // Store compatible tasks
1453
- if (data.compatible_tasks && data.compatible_tasks.length > 0) {
1454
- window.uploadedCompatibleTasks = data.compatible_tasks;
 
 
 
 
1455
  window.usingUploadedDbForTasks = true;
1456
 
1457
  // Enable task selection for uploaded DB
1458
  mode = 'task'; // Stay in task mode, not custom mode
1459
 
1460
- // Update UI
1461
- document.getElementById('upload-status').innerHTML = '✓ ' + data.filename + ' loaded (' + data.tables.length + ' tables) - <strong>' + data.compatible_tasks.length + ' tasks available</strong>';
 
1462
  document.getElementById('upload-status').style.color = 'var(--success)';
1463
  document.getElementById('back-to-tasks-btn').style.display = 'inline-flex';
1464
 
1465
  // Update schema panel with health data
1466
  renderSchema(data.tables, data.health_audits);
1467
 
1468
- // Show task selection for uploaded DB
1469
- showUploadedDbTaskSelector(data.compatible_tasks);
1470
 
1471
  // Ensure task selector is enabled
1472
  updateUIForMode();
1473
 
1474
- toast('Database uploaded! ' + data.compatible_tasks.length + ' tasks available', 'success');
1475
  } else {
1476
  // No compatible tasks - go to custom exploration mode
1477
  mode = 'custom';
1478
  window.uploadedCompatibleTasks = [];
 
1479
  window.usingUploadedDbForTasks = false;
1480
 
1481
- document.getElementById('upload-status').innerHTML = '✓ ' + data.filename + ' loaded (' + data.tables.length + ' tables) - <em>No RL tasks compatible</em>';
1482
  document.getElementById('upload-status').style.color = 'var(--text-secondary)';
1483
  document.getElementById('back-to-tasks-btn').style.display = 'inline-flex';
1484
 
@@ -1487,7 +1493,7 @@ async function uploadDatabase() {
1487
  document.getElementById('query-sql').placeholder = 'SELECT * FROM ' + firstCustomTable + ' LIMIT 10';
1488
  updateUIForMode();
1489
 
1490
- toast('Database uploaded for exploration only (no compatible RL tasks)', 'success');
1491
  }
1492
  } else {
1493
  document.getElementById('upload-error').style.display = 'block';
@@ -1503,8 +1509,8 @@ async function uploadDatabase() {
1503
  setLoading('upload', false);
1504
  }
1505
 
1506
- function showUploadedDbTaskSelector(compatibleTasks) {
1507
- // Create or update task selector for uploaded DB
1508
  let selector = document.getElementById('uploaded-db-task-selector');
1509
  if (!selector) {
1510
  selector = document.createElement('div');
@@ -1519,23 +1525,160 @@ function showUploadedDbTaskSelector(compatibleTasks) {
1519
  'type_repair': 'Type Repair',
1520
  'dedup_bug': 'Duplicate Bug',
1521
  'fk_integrity': 'FK Integrity',
1522
- 'schema_drift': 'Schema Drift'
 
1523
  };
1524
 
1525
- let html = '<div style="font-size: 14px; color: #2E7D32; margin-bottom: 8px;"><strong>📊 Select a Task to Run on Uploaded Database:</strong></div>';
1526
- html += '<div style="display: flex; gap: 8px; flex-wrap: wrap;">';
1527
 
1528
- compatibleTasks.forEach(taskId => {
1529
- html += '<button class="btn btn-primary" onclick="selectUploadedDbTask(\'' + taskId + '\')" style="font-size: 12px; padding: 6px 12px;">' + taskLabels[taskId] + '</button>';
1530
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1531
 
 
 
 
 
 
1532
  html += '</div>';
1533
- html += '<div style="margin-top: 8px; font-size: 11px; color: #558B2F;">These tasks will analyze your uploaded database</div>';
1534
 
1535
  selector.innerHTML = html;
1536
  selector.style.display = 'block';
1537
  }
1538
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1539
  function selectUploadedDbTask(taskId) {
1540
  // Update task selector to match
1541
  document.getElementById('task-select').value = taskId;
 
1449
  customDbFilename = data.filename;
1450
  firstCustomTable = data.tables[0]?.table_name || 'table';
1451
 
1452
+ // Store compatible tasks and semantic suggestions
1453
+ const hasLegacyTasks = data.compatible_tasks && data.compatible_tasks.length > 0;
1454
+ const hasSemanticTasks = data.semantic_tasks && data.semantic_tasks.length > 0;
1455
+
1456
+ if (hasLegacyTasks || hasSemanticTasks) {
1457
+ window.uploadedCompatibleTasks = data.compatible_tasks || [];
1458
+ window.uploadedSemanticTasks = data.semantic_tasks || [];
1459
  window.usingUploadedDbForTasks = true;
1460
 
1461
  // Enable task selection for uploaded DB
1462
  mode = 'task'; // Stay in task mode, not custom mode
1463
 
1464
+ // Update UI with smart message
1465
+ const totalTasks = (data.compatible_tasks?.length || 0) + (data.semantic_tasks?.length || 0);
1466
+ document.getElementById('upload-status').innerHTML = '✓ ' + data.filename + ' loaded (' + data.tables.length + ' tables) - <strong>' + totalTasks + ' smart task suggestions</strong>';
1467
  document.getElementById('upload-status').style.color = 'var(--success)';
1468
  document.getElementById('back-to-tasks-btn').style.display = 'inline-flex';
1469
 
1470
  // Update schema panel with health data
1471
  renderSchema(data.tables, data.health_audits);
1472
 
1473
+ // Show smart task selection
1474
+ showSmartTaskSelector(data.compatible_tasks, data.semantic_tasks, data.fingerprints);
1475
 
1476
  // Ensure task selector is enabled
1477
  updateUIForMode();
1478
 
1479
+ toast('Database uploaded! ' + totalTasks + ' smart task suggestions available', 'success');
1480
  } else {
1481
  // No compatible tasks - go to custom exploration mode
1482
  mode = 'custom';
1483
  window.uploadedCompatibleTasks = [];
1484
+ window.uploadedSemanticTasks = [];
1485
  window.usingUploadedDbForTasks = false;
1486
 
1487
+ document.getElementById('upload-status').innerHTML = '✓ ' + data.filename + ' loaded (' + data.tables.length + ' tables) - <em>Use Custom Mode to explore</em>';
1488
  document.getElementById('upload-status').style.color = 'var(--text-secondary)';
1489
  document.getElementById('back-to-tasks-btn').style.display = 'inline-flex';
1490
 
 
1493
  document.getElementById('query-sql').placeholder = 'SELECT * FROM ' + firstCustomTable + ' LIMIT 10';
1494
  updateUIForMode();
1495
 
1496
+ toast('Database uploaded for exploration (Custom Mode)', 'success');
1497
  }
1498
  } else {
1499
  document.getElementById('upload-error').style.display = 'block';
 
1509
  setLoading('upload', false);
1510
  }
1511
 
1512
+ function showSmartTaskSelector(legacyTasks, semanticTasks, fingerprints) {
1513
+ // Create or update smart task selector
1514
  let selector = document.getElementById('uploaded-db-task-selector');
1515
  if (!selector) {
1516
  selector = document.createElement('div');
 
1525
  'type_repair': 'Type Repair',
1526
  'dedup_bug': 'Duplicate Bug',
1527
  'fk_integrity': 'FK Integrity',
1528
+ 'schema_drift': 'Schema Drift',
1529
+ 'job_market_audit': 'Job Market Audit'
1530
  };
1531
 
1532
+ let html = '<div style="font-size: 14px; color: #2E7D32; margin-bottom: 8px;"><strong>🧠 Smart Task Suggestions:</strong></div>';
 
1533
 
1534
+ // Show semantic tasks first (they're smarter)
1535
+ if (semanticTasks && semanticTasks.length > 0) {
1536
+ html += '<div style="margin-bottom: 12px;">';
1537
+ html += '<div style="font-size: 12px; color: #558B2F; margin-bottom: 6px;">Based on your data analysis:</div>';
1538
+
1539
+ semanticTasks.forEach(task => {
1540
+ const confidence = Math.round(task.confidence * 100);
1541
+ const tableName = task.table_name;
1542
+ const fingerprint = fingerprints[tableName];
1543
+ const nullCount = fingerprint?.null_counts ? Object.values(fingerprint.null_counts).reduce((a, b) => a + b, 0) : 0;
1544
+
1545
+ html += '<div style="margin-bottom: 8px; padding: 8px; background: white; border-radius: 4px; border: 1px solid #C8E6C9;">';
1546
+ html += '<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">';
1547
+ html += '<span style="font-weight: 500; color: #2E7D32;">' + taskLabels[task.task_id] + '</span>';
1548
+ html += '<span style="font-size: 11px; background: #4CAF50; color: white; padding: 2px 6px; border-radius: 10px;">' + confidence + '% match</span>';
1549
+ html += '</div>';
1550
+ html += '<div style="font-size: 11px; color: #666; margin-bottom: 6px;">' + task.reason + '</div>';
1551
+
1552
+ if (task.requires_alias) {
1553
+ const suggestedAlias = task.suggested_alias || 'users';
1554
+ html += '<div style="display: flex; gap: 6px; align-items: center;">';
1555
+ html += '<button class="btn btn-primary" onclick="setTableAliasAndRunTask(\'' + tableName + '\', \'\' + suggestedAlias + '\', \'\' + task.task_id + '\')" style="font-size: 11px; padding: 4px 8px;">Run with Alias</button>';
1556
+ html += '<span style="font-size: 10px; color: #888;">Will treat \"' + tableName + '\" as \"' + suggestedAlias + '\"</span>';
1557
+ html += '</div>';
1558
+ } else {
1559
+ html += '<button class="btn btn-primary" onclick="selectUploadedDbTask(\'' + task.task_id + '\')" style="font-size: 11px; padding: 4px 8px;">Run Task</button>';
1560
+ }
1561
+
1562
+ html += '</div>';
1563
+ });
1564
+
1565
+ html += '</div>';
1566
+ }
1567
+
1568
+ // Show legacy tasks if any
1569
+ if (legacyTasks && legacyTasks.length > 0) {
1570
+ html += '<div style="margin-bottom: 12px;">';
1571
+ html += '<div style="font-size: 12px; color: #558B2F; margin-bottom: 6px;">Classic tasks (exact name match):</div>';
1572
+ html += '<div style="display: flex; gap: 8px; flex-wrap: wrap;">';
1573
+
1574
+ legacyTasks.forEach(taskId => {
1575
+ html += '<button class="btn btn-secondary" onclick="selectUploadedDbTask(\'' + taskId + '\')" style="font-size: 12px; padding: 6px 12px;">' + taskLabels[taskId] + '</button>';
1576
+ });
1577
+
1578
+ html += '</div></div>';
1579
+ }
1580
 
1581
+ // Add manual alias option
1582
+ html += '<div style="margin-top: 12px; padding: 8px; background: #FFF3E0; border-radius: 4px;">';
1583
+ html += '<div style="font-size: 11px; color: #E65100; margin-bottom: 6px;"><strong>Manual Override:</strong></div>';
1584
+ html += '<div style="font-size: 10px; color: #666; margin-bottom: 4px;">Treat any table as a specific task type:</div>';
1585
+ html += '<button onclick="showManualAliasDialog()" style="font-size: 10px; padding: 4px 8px; background: #FF9800; color: white; border: none; border-radius: 4px; cursor: pointer;">Set Table Alias</button>';
1586
  html += '</div>';
 
1587
 
1588
  selector.innerHTML = html;
1589
  selector.style.display = 'block';
1590
  }
1591
 
1592
+ function showUploadedDbTaskSelector(compatibleTasks) {
1593
+ // Legacy function - kept for compatibility
1594
+ showSmartTaskSelector(compatibleTasks, [], {});
1595
+ }
1596
+
1597
+ function setTableAliasAndRunTask(actualTable, aliasAs, taskId) {
1598
+ // Set the alias first
1599
+ api('POST', '/set-table-alias', {
1600
+ actual_table: actualTable,
1601
+ alias_as: aliasAs
1602
+ }).then(response => {
1603
+ if (response.ok) {
1604
+ toast(response.data.message, 'success');
1605
+ // Then select the task
1606
+ selectUploadedDbTask(taskId);
1607
+ } else {
1608
+ toast('Failed to set table alias', 'error');
1609
+ }
1610
+ });
1611
+ }
1612
+
1613
+ function showManualAliasDialog() {
1614
+ const tables = window.customDbSchema || [];
1615
+ if (tables.length === 0) {
1616
+ toast('No tables available', 'error');
1617
+ return;
1618
+ }
1619
+
1620
+ const tableNames = tables.map(t => t.table_name);
1621
+ const taskOptions = ['users', 'transactions', 'order_items', 'invoices', 'customers', 'events_v1', 'events_v2'];
1622
+
1623
+ let html = '<div style="padding: 16px;">';
1624
+ html += '<h3 style="margin-top: 0;">Set Table Alias</h3>';
1625
+ html += '<p style="color: #666; font-size: 14px;">Treat a table as if it has a different name for RL tasks</p>';
1626
+
1627
+ html += '<div style="margin-bottom: 12px;">';
1628
+ html += '<label style="display: block; margin-bottom: 4px; font-weight: 500;">Actual Table:</label>';
1629
+ html += '<select id="alias-table-select" style="width: 100%; padding: 6px; border: 1px solid #ddd; border-radius: 4px;">';
1630
+ tableNames.forEach(name => {
1631
+ html += '<option value="' + escapeHtml(name) + '">' + escapeHtml(name) + '</option>';
1632
+ });
1633
+ html += '</select>';
1634
+ html += '</div>';
1635
+
1636
+ html += '<div style="margin-bottom: 12px;">';
1637
+ html += '<label style="display: block; margin-bottom: 4px; font-weight: 500;">Treat as:</label>';
1638
+ html += '<select id="alias-as-select" style="width: 100%; padding: 6px; border: 1px solid #ddd; border-radius: 4px;">';
1639
+ taskOptions.forEach(name => {
1640
+ html += '<option value="' + name + '">' + name + '</option>';
1641
+ });
1642
+ html += '</select>';
1643
+ html += '</div>';
1644
+
1645
+ html += '<div style="display: flex; gap: 8px; justify-content: flex-end;">';
1646
+ html += '<button onclick="closeManualAliasDialog()" style="padding: 6px 12px; border: 1px solid #ddd; background: white; border-radius: 4px; cursor: pointer;">Cancel</button>';
1647
+ html += '<button onclick="applyManualAlias()" style="padding: 6px 12px; background: #2196F3; color: white; border: none; border-radius: 4px; cursor: pointer;">Apply</button>';
1648
+ html += '</div>';
1649
+
1650
+ html += '</div>';
1651
+
1652
+ // Create modal
1653
+ const modal = document.createElement('div');
1654
+ modal.id = 'alias-modal';
1655
+ modal.style.cssText = 'position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; z-index: 1000;';
1656
+ modal.innerHTML = html;
1657
+ document.body.appendChild(modal);
1658
+ }
1659
+
1660
+ function closeManualAliasDialog() {
1661
+ const modal = document.getElementById('alias-modal');
1662
+ if (modal) modal.remove();
1663
+ }
1664
+
1665
+ function applyManualAlias() {
1666
+ const actualTable = document.getElementById('alias-table-select').value;
1667
+ const aliasAs = document.getElementById('alias-as-select').value;
1668
+
1669
+ api('POST', '/set-table-alias', {
1670
+ actual_table: actualTable,
1671
+ alias_as: aliasAs
1672
+ }).then(response => {
1673
+ if (response.ok) {
1674
+ toast(response.data.message, 'success');
1675
+ closeManualAliasDialog();
1676
+ } else {
1677
+ toast('Failed to set table alias', 'error');
1678
+ }
1679
+ });
1680
+ }
1681
+
1682
  function selectUploadedDbTask(taskId) {
1683
  // Update task selector to match
1684
  document.getElementById('task-select').value = taskId;