v1.1.3: default server 0.0.0.0:80 + row-level clustering + filter UI + dataset selector
This commit is contained in:
@@ -111,19 +111,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Cluster Mode -->
|
||||
<div class="card" id="clusterModeCard">
|
||||
<label style="font-weight:600;">聚类模式</label>
|
||||
<div style="display:flex;gap:1.5rem;margin-top:0.5rem;">
|
||||
<label><input type="radio" name="clusterMode" value="entity" checked onchange="clusterMode='entity'"> 实体聚合后聚类(默认)</label>
|
||||
<label><input type="radio" name="clusterMode" value="raw" onchange="clusterMode='raw'"> 逐行直接聚类</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filter builder card -->
|
||||
<div class="card" id="filterCard" style="display:none;">
|
||||
<div class="card" id="filterCard" style="background:#f0f4ff;border-color:#c8d6e5;">
|
||||
<h3>🔍 数据筛选</h3>
|
||||
<div id="filterRows">
|
||||
<div id="filterNoDataset" style="text-align:center;color:#999;padding:1rem;font-size:0.9rem;">选择数据集后可用</div>
|
||||
<div id="filterRows" style="display:none;">
|
||||
<div class="filter-row" data-idx="0" style="display:flex;gap:0.5rem;align-items:center;margin-bottom:0.4rem;">
|
||||
<select class="filter-col" style="flex:1;padding:0.35rem;border:1px solid #ccc;border-radius:4px;"><option value="">-- 列 --</option></select>
|
||||
<select class="filter-op" style="width:130px;padding:0.35rem;border:1px solid #ccc;border-radius:4px;">
|
||||
@@ -139,12 +131,13 @@
|
||||
<button class="btn" onclick="removeFilterRow(this)" style="background:#dc3545;color:#fff;font-size:0.8rem;padding:0.2rem 0.5rem;display:none;">✕</button>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin:0.5rem 0;display:flex;gap:0.5rem;align-items:center;">
|
||||
<div id="filterControls" style="display:none;margin:0.5rem 0;gap:0.5rem;align-items:center;">
|
||||
<label style="font-size:0.85rem;white-space:nowrap;">逻辑:</label>
|
||||
<select id="filterLogic" style="padding:0.35rem;border:1px solid #ccc;border-radius:4px;">
|
||||
<option value="and">AND</option><option value="or">OR</option>
|
||||
</select>
|
||||
<button class="btn" onclick="addFilterRow()" style="font-size:0.8rem;background:#e8f0fe;color:#4361ee;">+ 添加条件</button>
|
||||
<button class="btn" onclick="resetFilter()" style="font-size:0.8rem;background:#fce4ec;color:#c62828;">重置</button>
|
||||
<button class="btn btn-primary" onclick="applyFilter()" style="margin-left:auto;">应用筛选</button>
|
||||
</div>
|
||||
<div id="filterResult" style="display:none;margin-top:0.5rem;padding:0.5rem;background:#e8f5e9;border-radius:4px;font-size:0.85rem;"></div>
|
||||
@@ -181,7 +174,6 @@ const CATEGORIES = {
|
||||
let stepCounter = 0;
|
||||
const workflow = [];
|
||||
let running = false;
|
||||
var clusterMode = 'entity';
|
||||
|
||||
// ── Dataset selector with status badges ──
|
||||
const DATASETS_WITH_STATUS = {{ datasets_with_status_json|safe }};
|
||||
@@ -362,16 +354,16 @@ async function executeStep(idx) {
|
||||
resultDiv.style.display = 'none';
|
||||
const params = collectParams(idx);
|
||||
|
||||
// Cluster mode: skip build_entity_profiles in raw mode
|
||||
if (clusterMode === 'raw' && step.tool.name === 'build_entity_profiles') {
|
||||
// Raw row-level clustering: skip entity aggregation entirely
|
||||
if (step.tool.name === 'build_entity_profiles') {
|
||||
step.status = 'done';
|
||||
resultDiv.textContent = '[已跳过] 逐行直接聚类模式,无需实体聚合';
|
||||
resultDiv.style.display = 'block';
|
||||
renderSteps();
|
||||
return;
|
||||
}
|
||||
// Pass cluster_mode to run_clustering tool
|
||||
if (clusterMode === 'raw' && step.tool.name === 'run_clustering') {
|
||||
// Always cluster raw rows directly
|
||||
if (step.tool.name === 'run_clustering') {
|
||||
params.cluster_mode = 'raw';
|
||||
}
|
||||
|
||||
@@ -578,9 +570,30 @@ const DATASET_COLUMNS = {
|
||||
// ── Filter builder ──
|
||||
function onDatasetChange() {
|
||||
const dsId = document.getElementById('datasetSelect').value;
|
||||
const filterCard = document.getElementById('filterCard');
|
||||
if (!dsId) { filterCard.style.display = 'none'; return; }
|
||||
filterCard.style.display = 'block';
|
||||
const noDatasetMsg = document.getElementById('filterNoDataset');
|
||||
const filterRows = document.getElementById('filterRows');
|
||||
const filterControls = document.getElementById('filterControls');
|
||||
const filterResult = document.getElementById('filterResult');
|
||||
|
||||
if (!dsId) {
|
||||
// No dataset selected: show placeholder, hide filter UI
|
||||
noDatasetMsg.style.display = 'block';
|
||||
filterRows.style.display = 'none';
|
||||
filterControls.style.display = 'none';
|
||||
filterResult.style.display = 'none';
|
||||
// Clear column dropdowns
|
||||
document.querySelectorAll('.filter-col').forEach(sel => {
|
||||
sel.innerHTML = '<option value="">-- 请先选择数据集 --</option>';
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Dataset selected: show filter UI, hide placeholder
|
||||
noDatasetMsg.style.display = 'none';
|
||||
filterRows.style.display = 'block';
|
||||
filterControls.style.display = 'flex';
|
||||
|
||||
// Populate column dropdowns
|
||||
const cols = DATASET_COLUMNS[dsId] || [];
|
||||
document.querySelectorAll('.filter-col').forEach(sel => {
|
||||
const cur = sel.value;
|
||||
@@ -591,7 +604,7 @@ function onDatasetChange() {
|
||||
|
||||
function addFilterRow() {
|
||||
const rows = document.querySelectorAll('.filter-row');
|
||||
if (rows.length >= 2) return; // MVP: max 2 rows
|
||||
if (rows.length >= 5) return; // max 5 rows
|
||||
const template = rows[0].cloneNode(true);
|
||||
template.querySelector('.filter-val').value = '';
|
||||
template.querySelector('.filter-col').selectedIndex = 0;
|
||||
@@ -608,6 +621,20 @@ function removeFilterRow(btn) {
|
||||
btn.closest('.filter-row').remove();
|
||||
}
|
||||
|
||||
function resetFilter() {
|
||||
// Remove all rows except the first, then reset the first row
|
||||
const rows = document.querySelectorAll('.filter-row');
|
||||
for (let i = rows.length - 1; i >= 1; i--) {
|
||||
rows[i].remove();
|
||||
}
|
||||
const firstRow = rows[0];
|
||||
firstRow.querySelector('.filter-val').value = '';
|
||||
firstRow.querySelector('.filter-col').selectedIndex = 0;
|
||||
firstRow.querySelector('.filter-op').selectedIndex = 0;
|
||||
firstRow.querySelector('button').style.display = 'none';
|
||||
document.getElementById('filterResult').style.display = 'none';
|
||||
}
|
||||
|
||||
function collectFilters() {
|
||||
const filters = [];
|
||||
document.querySelectorAll('.filter-row').forEach(row => {
|
||||
@@ -650,7 +677,7 @@ async function applyFilter() {
|
||||
|
||||
const resultDiv = document.getElementById('filterResult');
|
||||
resultDiv.style.display = 'block';
|
||||
resultDiv.textContent = '筛选完成: ' + data.dataset_id + ' (' + data.row_count + ' 行)';
|
||||
resultDiv.innerHTML = '<strong>✅ 筛选完成</strong>: 数据集 <code>' + data.dataset_id + '</code>,共 <strong>' + data.row_count + '</strong> 行';
|
||||
showSuccess('筛选完成: ' + data.row_count + ' 行');
|
||||
} catch(e) {
|
||||
showError('筛选请求失败: ' + e.message);
|
||||
|
||||
Reference in New Issue
Block a user