cnhkmcp 2.1.2__py3-none-any.whl → 2.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cnhkmcp-2.1.2.dist-info → cnhkmcp-2.1.3.dist-info}/METADATA +1 -1
- cnhkmcp-2.1.3.dist-info/RECORD +6 -0
- cnhkmcp-2.1.3.dist-info/top_level.txt +1 -0
- cnhkmcp/__init__.py +0 -125
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/README.md +0 -38
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/ace.log +0 -0
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/config.json +0 -6
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/ace_lib.py +0 -1510
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_datasets.py +0 -157
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_documentation.py +0 -132
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/fetch_all_operators.py +0 -99
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/get_knowledgeBase_tool/helpful_functions.py +0 -180
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/icon.ico +0 -0
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/icon.png +0 -0
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/knowledge/test.txt +0 -1
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/main.py +0 -576
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/process_knowledge_base.py +0 -281
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/rag_engine.py +0 -408
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/requirements.txt +0 -7
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242/run.bat +0 -3
- cnhkmcp/untracked/AI/321/206/320/261/320/234/321/211/320/255/320/262/321/206/320/237/320/242/321/204/342/225/227/342/225/242//321/211/320/266/320/246/321/206/320/274/320/261/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/231/320/243/321/205/342/225/235/320/220/321/206/320/230/320/241.py +0 -265
- cnhkmcp/untracked/APP/.gitignore +0 -32
- cnhkmcp/untracked/APP/MODULAR_STRUCTURE.md +0 -112
- cnhkmcp/untracked/APP/README.md +0 -309
- cnhkmcp/untracked/APP/Tranformer/Transformer.py +0 -4985
- cnhkmcp/untracked/APP/Tranformer/ace.log +0 -0
- cnhkmcp/untracked/APP/Tranformer/ace_lib.py +0 -1510
- cnhkmcp/untracked/APP/Tranformer/helpful_functions.py +0 -180
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates.json +0 -2421
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_candidates_/321/207/320/264/342/225/221/321/204/342/225/233/320/233.json +0 -654
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_error.json +0 -1034
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_success.json +0 -444
- cnhkmcp/untracked/APP/Tranformer/output/Alpha_generated_expressions_/321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/320/237/320/277/321/207/320/253/342/224/244/321/206/320/236/320/265/321/210/342/225/234/342/225/234/321/205/320/225/320/265Machine_lib.json +0 -22
- cnhkmcp/untracked/APP/Tranformer/parsetab.py +0 -60
- cnhkmcp/untracked/APP/Tranformer/template_summary.txt +0 -3182
- cnhkmcp/untracked/APP/Tranformer/transformer_config.json +0 -7
- cnhkmcp/untracked/APP/Tranformer/validator.py +0 -889
- cnhkmcp/untracked/APP/ace.log +0 -69
- cnhkmcp/untracked/APP/ace_lib.py +0 -1510
- cnhkmcp/untracked/APP/blueprints/__init__.py +0 -6
- cnhkmcp/untracked/APP/blueprints/feature_engineering.py +0 -347
- cnhkmcp/untracked/APP/blueprints/idea_house.py +0 -221
- cnhkmcp/untracked/APP/blueprints/inspiration_house.py +0 -432
- cnhkmcp/untracked/APP/blueprints/paper_analysis.py +0 -570
- cnhkmcp/untracked/APP/custom_templates/templates.json +0 -1257
- cnhkmcp/untracked/APP/give_me_idea/BRAIN_Alpha_Template_Expert_SystemPrompt.md +0 -400
- cnhkmcp/untracked/APP/give_me_idea/ace_lib.py +0 -1510
- cnhkmcp/untracked/APP/give_me_idea/alpha_data_specific_template_master.py +0 -252
- cnhkmcp/untracked/APP/give_me_idea/fetch_all_datasets.py +0 -157
- cnhkmcp/untracked/APP/give_me_idea/fetch_all_operators.py +0 -99
- cnhkmcp/untracked/APP/give_me_idea/helpful_functions.py +0 -180
- cnhkmcp/untracked/APP/give_me_idea/what_is_Alpha_template.md +0 -11
- cnhkmcp/untracked/APP/helpful_functions.py +0 -180
- cnhkmcp/untracked/APP/hkSimulator/ace_lib.py +0 -1497
- cnhkmcp/untracked/APP/hkSimulator/autosimulator.py +0 -447
- cnhkmcp/untracked/APP/hkSimulator/helpful_functions.py +0 -180
- cnhkmcp/untracked/APP/mirror_config.txt +0 -20
- cnhkmcp/untracked/APP/operaters.csv +0 -129
- cnhkmcp/untracked/APP/requirements.txt +0 -53
- cnhkmcp/untracked/APP/run_app.bat +0 -28
- cnhkmcp/untracked/APP/run_app.sh +0 -34
- cnhkmcp/untracked/APP/setup_tsinghua.bat +0 -39
- cnhkmcp/untracked/APP/setup_tsinghua.sh +0 -43
- cnhkmcp/untracked/APP/simulator/alpha_submitter.py +0 -404
- cnhkmcp/untracked/APP/simulator/simulator_wqb.py +0 -618
- cnhkmcp/untracked/APP/ssrn-3332513.pdf +6 -109201
- cnhkmcp/untracked/APP/static/brain.js +0 -589
- cnhkmcp/untracked/APP/static/decoder.js +0 -1540
- cnhkmcp/untracked/APP/static/feature_engineering.js +0 -1729
- cnhkmcp/untracked/APP/static/idea_house.js +0 -937
- cnhkmcp/untracked/APP/static/inspiration.js +0 -465
- cnhkmcp/untracked/APP/static/inspiration_house.js +0 -868
- cnhkmcp/untracked/APP/static/paper_analysis.js +0 -390
- cnhkmcp/untracked/APP/static/script.js +0 -3082
- cnhkmcp/untracked/APP/static/simulator.js +0 -597
- cnhkmcp/untracked/APP/static/styles.css +0 -3127
- cnhkmcp/untracked/APP/static/usage_widget.js +0 -508
- cnhkmcp/untracked/APP/templates/alpha_inspector.html +0 -511
- cnhkmcp/untracked/APP/templates/feature_engineering.html +0 -960
- cnhkmcp/untracked/APP/templates/idea_house.html +0 -564
- cnhkmcp/untracked/APP/templates/index.html +0 -932
- cnhkmcp/untracked/APP/templates/inspiration_house.html +0 -861
- cnhkmcp/untracked/APP/templates/paper_analysis.html +0 -91
- cnhkmcp/untracked/APP/templates/simulator.html +0 -343
- cnhkmcp/untracked/APP/templates/transformer_web.html +0 -580
- cnhkmcp/untracked/APP/usage.md +0 -351
- cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/ace_lib.py +0 -1510
- cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/brain_alpha_inspector.py +0 -712
- cnhkmcp/untracked/APP//321/207/342/225/235/320/250/321/205/320/230/320/226/321/204/342/225/225/320/220/321/211/320/221/320/243/321/206/320/261/320/265/helpful_functions.py +0 -180
- cnhkmcp/untracked/APP//321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/231/320/243/321/205/342/225/235/320/220/321/206/320/230/320/241.py +0 -2456
- cnhkmcp/untracked/arXiv_API_Tool_Manual.md +0 -490
- cnhkmcp/untracked/arxiv_api.py +0 -229
- cnhkmcp/untracked/forum_functions.py +0 -998
- cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/forum_functions.py +0 -407
- cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/platform_functions.py +0 -2415
- cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272/user_config.json +0 -31
- cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272//321/210/320/276/320/271AI/321/210/320/277/342/225/227/321/210/342/224/220/320/251/321/204/342/225/225/320/272/321/206/320/246/320/227/321/206/320/261/320/263/321/206/320/255/320/265/321/205/320/275/320/266/321/204/342/225/235/320/252/321/204/342/225/225/320/233/321/210/342/225/234/342/225/234/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270.md +0 -101
- cnhkmcp/untracked/mcp/321/206/320/246/320/227/321/204/342/225/227/342/225/242/321/210/320/276/342/225/221/321/205/320/255/320/253/321/207/320/231/320/2302_/321/205/320/266/320/222/321/206/320/256/320/254/321/205/320/236/320/257/321/207/320/231/320/230/321/205/320/240/320/277/321/205/320/232/320/270/321/204/342/225/225/320/235/321/204/342/225/221/320/226/321/206/342/225/241/320/237/321/210/320/267/320/230/321/205/320/251/320/270/321/205/342/226/221/342/226/222/321/210/320/277/320/245/321/210/342/224/220/320/251/321/204/342/225/225/320/272//321/211/320/225/320/235/321/207/342/225/234/320/276/321/205/320/231/320/235/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/230/320/241_/321/205/320/276/320/231/321/210/320/263/320/225/321/205/342/224/220/320/225/321/210/320/266/320/221/321/204/342/225/233/320/255/321/210/342/225/241/320/246/321/205/320/234/320/225.py +0 -190
- cnhkmcp/untracked/platform_functions.py +0 -2886
- cnhkmcp/untracked/sample_mcp_config.json +0 -11
- cnhkmcp/untracked/user_config.json +0 -31
- cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/320/237/320/222/321/210/320/220/320/223/321/206/320/246/320/227/321/206/320/261/320/263_BRAIN_Alpha_Test_Requirements_and_Tips.md +0 -202
- cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_Alpha_explaination_workflow.md +0 -56
- cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_BRAIN_6_Tips_Datafield_Exploration_Guide.md +0 -194
- cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_BRAIN_Alpha_Improvement_Workflow.md +0 -101
- cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_Dataset_Exploration_Expert_Manual.md +0 -436
- cnhkmcp/untracked//321/207/320/264/342/225/221/321/204/342/225/233/320/233/321/205/342/225/226/320/265/321/204/342/225/234/320/254/321/206/342/225/241/320/221_daily_report_workflow.md +0 -128
- cnhkmcp/untracked//321/211/320/225/320/235/321/207/342/225/234/320/276/321/205/320/231/320/235/321/210/342/224/220/320/240/321/210/320/261/320/234/321/206/320/230/320/241_/321/205/320/276/320/231/321/210/320/263/320/225/321/205/342/224/220/320/225/321/210/320/266/320/221/321/204/342/225/233/320/255/321/210/342/225/241/320/246/321/205/320/234/320/225.py +0 -190
- cnhkmcp-2.1.2.dist-info/RECORD +0 -111
- cnhkmcp-2.1.2.dist-info/top_level.txt +0 -1
- {cnhkmcp-2.1.2.dist-info → cnhkmcp-2.1.3.dist-info}/WHEEL +0 -0
- {cnhkmcp-2.1.2.dist-info → cnhkmcp-2.1.3.dist-info}/entry_points.txt +0 -0
- {cnhkmcp-2.1.2.dist-info → cnhkmcp-2.1.3.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,937 +0,0 @@
|
|
|
1
|
-
// Idea House JavaScript - Handles data field selection and Coze API processing
|
|
2
|
-
|
|
3
|
-
// Global variables
|
|
4
|
-
let dataFields = [];
|
|
5
|
-
let filteredDataFields = [];
|
|
6
|
-
let selectedFields = new Map(); // Map of field_id -> description
|
|
7
|
-
|
|
8
|
-
// Filter state variables
|
|
9
|
-
let columnFilters = {
|
|
10
|
-
id: '',
|
|
11
|
-
description: '',
|
|
12
|
-
type: '',
|
|
13
|
-
coverage: { min: null, max: null },
|
|
14
|
-
userCount: null,
|
|
15
|
-
alphaCount: null
|
|
16
|
-
};
|
|
17
|
-
let sortColumn = null;
|
|
18
|
-
let sortOrder = 'asc';
|
|
19
|
-
|
|
20
|
-
// Initialize when DOM is loaded
|
|
21
|
-
document.addEventListener('DOMContentLoaded', function() {
|
|
22
|
-
// Set up event listeners
|
|
23
|
-
document.getElementById('loadDataFieldsBtn').addEventListener('click', loadDataFields);
|
|
24
|
-
document.getElementById('clearSelectionBtn').addEventListener('click', clearSelection);
|
|
25
|
-
document.getElementById('processFieldsBtn').addEventListener('click', processSelectedFields);
|
|
26
|
-
|
|
27
|
-
// Set up API token toggle button
|
|
28
|
-
const toggleBtn = document.getElementById('toggleApiTokenBtn');
|
|
29
|
-
const tokenInput = document.getElementById('cozeApiTokenInput');
|
|
30
|
-
|
|
31
|
-
toggleBtn.addEventListener('click', function() {
|
|
32
|
-
if (tokenInput.type === 'password') {
|
|
33
|
-
tokenInput.type = 'text';
|
|
34
|
-
toggleBtn.textContent = 'Hide';
|
|
35
|
-
} else {
|
|
36
|
-
tokenInput.type = 'password';
|
|
37
|
-
toggleBtn.textContent = 'Show';
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// Load saved configuration
|
|
42
|
-
loadSavedCozeConfig();
|
|
43
|
-
|
|
44
|
-
// Set up save configuration button
|
|
45
|
-
document.getElementById('saveCozeConfigBtn').addEventListener('click', saveCozeConfig);
|
|
46
|
-
|
|
47
|
-
// Set up clear configuration button
|
|
48
|
-
document.getElementById('clearCozeConfigBtn').addEventListener('click', clearCozeConfig);
|
|
49
|
-
|
|
50
|
-
// Set up filter event listeners
|
|
51
|
-
setupFilterEventListeners();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Load data fields from BRAIN API
|
|
55
|
-
async function loadDataFields() {
|
|
56
|
-
const region = document.getElementById('regionInput').value;
|
|
57
|
-
const delay = document.getElementById('delayInput').value;
|
|
58
|
-
const universe = document.getElementById('universeInput').value;
|
|
59
|
-
const datasetId = document.getElementById('datasetInput').value;
|
|
60
|
-
|
|
61
|
-
// Show loading state
|
|
62
|
-
document.getElementById('dataFieldsStats').textContent = 'Loading data fields...';
|
|
63
|
-
document.getElementById('tableContainer').style.display = 'none';
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
// Get session ID from localStorage or cookie
|
|
67
|
-
const sessionId = localStorage.getItem('brain_session_id');
|
|
68
|
-
|
|
69
|
-
if (!sessionId) {
|
|
70
|
-
alert('Please connect to BRAIN first from the main page');
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Call the proxy endpoint
|
|
75
|
-
const params = new URLSearchParams({
|
|
76
|
-
region: region,
|
|
77
|
-
delay: delay,
|
|
78
|
-
universe: universe,
|
|
79
|
-
dataset_id: datasetId
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// Log the API calls
|
|
83
|
-
console.log('🚀 Making API calls to fetch data fields and dataset description');
|
|
84
|
-
console.log('📋 Parameters:', {
|
|
85
|
-
region: region,
|
|
86
|
-
delay: delay,
|
|
87
|
-
universe: universe,
|
|
88
|
-
dataset_id: datasetId
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// Fetch data fields and dataset description in parallel
|
|
92
|
-
const [dataFieldsResponse, descriptionResponse] = await Promise.all([
|
|
93
|
-
fetch(`/idea-house/api/get-datafields-proxy?${params}`, {
|
|
94
|
-
method: 'GET',
|
|
95
|
-
headers: {
|
|
96
|
-
'Session-ID': sessionId
|
|
97
|
-
}
|
|
98
|
-
}),
|
|
99
|
-
fetch(`/idea-house/api/get-dataset-description?${params}`, {
|
|
100
|
-
method: 'GET',
|
|
101
|
-
headers: {
|
|
102
|
-
'Session-ID': sessionId
|
|
103
|
-
}
|
|
104
|
-
})
|
|
105
|
-
]);
|
|
106
|
-
|
|
107
|
-
console.log('📥 Received responses:');
|
|
108
|
-
console.log(' Data fields status:', dataFieldsResponse.status);
|
|
109
|
-
console.log(' Dataset description status:', descriptionResponse.status);
|
|
110
|
-
|
|
111
|
-
if (!dataFieldsResponse.ok) {
|
|
112
|
-
const errorData = await dataFieldsResponse.json();
|
|
113
|
-
throw new Error(errorData.error || 'Failed to fetch data fields');
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
dataFields = await dataFieldsResponse.json();
|
|
117
|
-
|
|
118
|
-
// Get dataset description if available
|
|
119
|
-
let datasetDescription = '';
|
|
120
|
-
if (descriptionResponse.ok) {
|
|
121
|
-
console.log('✅ Dataset description response OK, parsing JSON...');
|
|
122
|
-
const descriptionData = await descriptionResponse.json();
|
|
123
|
-
console.log('📄 Description data:', descriptionData);
|
|
124
|
-
|
|
125
|
-
if (descriptionData.success) {
|
|
126
|
-
datasetDescription = descriptionData.description;
|
|
127
|
-
// Store it globally for later use
|
|
128
|
-
window.currentDatasetDescription = datasetDescription;
|
|
129
|
-
console.log('✅ Dataset description stored:', datasetDescription);
|
|
130
|
-
} else {
|
|
131
|
-
console.log('⚠️ Description response success=false');
|
|
132
|
-
}
|
|
133
|
-
} else {
|
|
134
|
-
console.log('❌ Dataset description response not OK:', descriptionResponse.status);
|
|
135
|
-
try {
|
|
136
|
-
const errorData = await descriptionResponse.json();
|
|
137
|
-
console.log('❌ Error details:', errorData);
|
|
138
|
-
} catch (e) {
|
|
139
|
-
console.log('❌ Could not parse error response');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Update stats
|
|
144
|
-
document.getElementById('dataFieldsStats').textContent = `Loaded ${dataFields.length} data fields`;
|
|
145
|
-
|
|
146
|
-
// Populate table with dataset description
|
|
147
|
-
populateDataFieldsTable(datasetDescription);
|
|
148
|
-
|
|
149
|
-
// Show table
|
|
150
|
-
document.getElementById('tableContainer').style.display = 'block';
|
|
151
|
-
|
|
152
|
-
} catch (error) {
|
|
153
|
-
console.error('Failed to load data fields:', error);
|
|
154
|
-
document.getElementById('dataFieldsStats').textContent = `Error: ${error.message}`;
|
|
155
|
-
alert(`Failed to load data fields: ${error.message}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Populate the data fields table with filtering and sorting
|
|
160
|
-
function populateDataFieldsTable(datasetDescription) {
|
|
161
|
-
console.log('📊 populateDataFieldsTable called with description:', datasetDescription);
|
|
162
|
-
|
|
163
|
-
const tableBody = document.getElementById('dataFieldsTableBody');
|
|
164
|
-
const highCoverageFilter = document.getElementById('filterHighCoverage')?.checked || false;
|
|
165
|
-
const popularFilter = document.getElementById('filterPopular')?.checked || false;
|
|
166
|
-
const matrixOnlyFilter = document.getElementById('filterMatrixOnly')?.checked || false;
|
|
167
|
-
|
|
168
|
-
// Display dataset description if available
|
|
169
|
-
if (datasetDescription) {
|
|
170
|
-
console.log('🎯 Displaying passed dataset description');
|
|
171
|
-
displayDatasetDescription(datasetDescription);
|
|
172
|
-
} else if (window.currentDatasetDescription) {
|
|
173
|
-
console.log('🎯 Displaying stored dataset description');
|
|
174
|
-
displayDatasetDescription(window.currentDatasetDescription);
|
|
175
|
-
} else {
|
|
176
|
-
console.log('⚠️ No dataset description available');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Apply filters
|
|
180
|
-
filteredDataFields = dataFields.filter(field => {
|
|
181
|
-
// Column-specific filters
|
|
182
|
-
// ID filter
|
|
183
|
-
if (columnFilters.id && !field.id.toLowerCase().includes(columnFilters.id.toLowerCase())) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Description filter
|
|
188
|
-
if (columnFilters.description && !field.description.toLowerCase().includes(columnFilters.description.toLowerCase())) {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Type filter
|
|
193
|
-
if (columnFilters.type && field.type !== columnFilters.type) {
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Coverage range filter
|
|
198
|
-
if (columnFilters.coverage.min !== null && field.coverage * 100 < columnFilters.coverage.min) {
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
if (columnFilters.coverage.max !== null && field.coverage * 100 > columnFilters.coverage.max) {
|
|
202
|
-
return false;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// User count filter
|
|
206
|
-
if (columnFilters.userCount !== null && field.userCount < columnFilters.userCount) {
|
|
207
|
-
return false;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// Alpha count filter
|
|
211
|
-
if (columnFilters.alphaCount !== null && field.alphaCount < columnFilters.alphaCount) {
|
|
212
|
-
return false;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// High coverage filter
|
|
216
|
-
if (highCoverageFilter && field.coverage < 0.9) {
|
|
217
|
-
return false;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Popular filter
|
|
221
|
-
if (popularFilter && field.userCount < 1000) {
|
|
222
|
-
return false;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Matrix type filter
|
|
226
|
-
if (matrixOnlyFilter && field.type !== 'MATRIX') {
|
|
227
|
-
return false;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
return true;
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
// Sort filtered data fields
|
|
234
|
-
if (sortColumn) {
|
|
235
|
-
filteredDataFields.sort((a, b) => {
|
|
236
|
-
let aVal = a[sortColumn];
|
|
237
|
-
let bVal = b[sortColumn];
|
|
238
|
-
|
|
239
|
-
// Handle numeric values
|
|
240
|
-
if (sortColumn === 'coverage' || sortColumn === 'userCount' || sortColumn === 'alphaCount') {
|
|
241
|
-
aVal = Number(aVal);
|
|
242
|
-
bVal = Number(bVal);
|
|
243
|
-
} else {
|
|
244
|
-
// String comparison
|
|
245
|
-
aVal = String(aVal).toLowerCase();
|
|
246
|
-
bVal = String(bVal).toLowerCase();
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (aVal < bVal) return sortOrder === 'asc' ? -1 : 1;
|
|
250
|
-
if (aVal > bVal) return sortOrder === 'asc' ? 1 : -1;
|
|
251
|
-
return 0;
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// Clear table
|
|
256
|
-
tableBody.innerHTML = '';
|
|
257
|
-
|
|
258
|
-
if (filteredDataFields.length === 0) {
|
|
259
|
-
tableBody.innerHTML = '<tr><td colspan="7" style="text-align: center; color: #666; padding: 40px;">No data fields found matching the filters</td></tr>';
|
|
260
|
-
updateDataFieldsStats();
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Create table rows
|
|
265
|
-
filteredDataFields.forEach(field => {
|
|
266
|
-
const row = document.createElement('tr');
|
|
267
|
-
row.dataset.fieldId = field.id;
|
|
268
|
-
row.dataset.fieldDescription = field.description;
|
|
269
|
-
|
|
270
|
-
if (selectedFields.has(field.id)) {
|
|
271
|
-
row.classList.add('selected');
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
row.innerHTML = `
|
|
275
|
-
<td>
|
|
276
|
-
<input type="checkbox" class="field-checkbox" data-field-id="${field.id}" data-field-description="${field.description}" ${selectedFields.has(field.id) ? 'checked' : ''}>
|
|
277
|
-
</td>
|
|
278
|
-
<td><span class="data-field-id">${field.id}</span></td>
|
|
279
|
-
<td><span class="data-field-description">${field.description}</span></td>
|
|
280
|
-
<td><span class="data-field-type">${field.type || 'N/A'}</span></td>
|
|
281
|
-
<td><span class="data-field-coverage">${field.coverage ? (field.coverage * 100).toFixed(1) + '%' : 'N/A'}</span></td>
|
|
282
|
-
<td><span class="data-field-count">${field.userCount ? field.userCount.toLocaleString() : 'N/A'}</span></td>
|
|
283
|
-
<td><span class="data-field-count">${field.alphaCount ? field.alphaCount.toLocaleString() : 'N/A'}</span></td>
|
|
284
|
-
`;
|
|
285
|
-
|
|
286
|
-
// Add click handler for row
|
|
287
|
-
row.addEventListener('click', function(e) {
|
|
288
|
-
if (e.target.type !== 'checkbox') {
|
|
289
|
-
const checkbox = row.querySelector('.field-checkbox');
|
|
290
|
-
checkbox.checked = !checkbox.checked;
|
|
291
|
-
handleFieldSelection(checkbox);
|
|
292
|
-
}
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
// Add change handler for checkbox
|
|
296
|
-
const checkbox = row.querySelector('.field-checkbox');
|
|
297
|
-
checkbox.addEventListener('change', function() {
|
|
298
|
-
handleFieldSelection(this);
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
tableBody.appendChild(row);
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
// Update stats and populate type filter
|
|
305
|
-
updateDataFieldsStats();
|
|
306
|
-
populateTypeFilter();
|
|
307
|
-
updateSelectAllCheckbox();
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// Handle field selection
|
|
311
|
-
function handleFieldSelection(checkbox) {
|
|
312
|
-
const fieldId = checkbox.dataset.fieldId;
|
|
313
|
-
const fieldDescription = checkbox.dataset.fieldDescription;
|
|
314
|
-
const row = checkbox.closest('tr');
|
|
315
|
-
|
|
316
|
-
if (checkbox.checked) {
|
|
317
|
-
selectedFields.set(fieldId, fieldDescription);
|
|
318
|
-
row.classList.add('selected');
|
|
319
|
-
} else {
|
|
320
|
-
selectedFields.delete(fieldId);
|
|
321
|
-
row.classList.remove('selected');
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
updateSelectedFieldsDisplay();
|
|
325
|
-
updateDataFieldsStats();
|
|
326
|
-
updateSelectAllCheckbox();
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Update the display of selected fields
|
|
330
|
-
function updateSelectedFieldsDisplay() {
|
|
331
|
-
const selectedFieldsList = document.getElementById('selectedFieldsList');
|
|
332
|
-
const selectedFieldsSection = document.getElementById('selectedFieldsSection');
|
|
333
|
-
|
|
334
|
-
if (selectedFields.size === 0) {
|
|
335
|
-
selectedFieldsSection.style.display = 'none';
|
|
336
|
-
return;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
selectedFieldsSection.style.display = 'block';
|
|
340
|
-
selectedFieldsList.innerHTML = '';
|
|
341
|
-
|
|
342
|
-
selectedFields.forEach((description, fieldId) => {
|
|
343
|
-
const fieldItem = document.createElement('div');
|
|
344
|
-
fieldItem.className = 'selected-field-item';
|
|
345
|
-
fieldItem.textContent = `${fieldId}: ${description}`;
|
|
346
|
-
selectedFieldsList.appendChild(fieldItem);
|
|
347
|
-
});
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
// Clear all selections
|
|
351
|
-
function clearSelection() {
|
|
352
|
-
selectedFields.clear();
|
|
353
|
-
|
|
354
|
-
// Uncheck all checkboxes and remove selected class
|
|
355
|
-
document.querySelectorAll('.field-checkbox').forEach(checkbox => {
|
|
356
|
-
checkbox.checked = false;
|
|
357
|
-
checkbox.closest('tr').classList.remove('selected');
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
updateSelectedFieldsDisplay();
|
|
361
|
-
updateDataFieldsStats();
|
|
362
|
-
updateSelectAllCheckbox();
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Process selected fields using Coze API
|
|
366
|
-
async function processSelectedFields() {
|
|
367
|
-
if (selectedFields.size === 0) {
|
|
368
|
-
alert('Please select at least one field');
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// Show loading overlay with Coze API specific message
|
|
373
|
-
const loadingOverlay = document.getElementById('loadingOverlay');
|
|
374
|
-
const loadingContent = loadingOverlay.querySelector('.loading-content');
|
|
375
|
-
loadingContent.innerHTML = `
|
|
376
|
-
<h3>🚀 Sending Request to Coze API...</h3>
|
|
377
|
-
<p>Processing ${selectedFields.size} selected fields through Coze workflow</p>
|
|
378
|
-
<p style="font-size: 14px; color: #666; margin-top: 10px;">
|
|
379
|
-
📡 Connecting to Coze API...<br>
|
|
380
|
-
⚙️ Running workflow analysis...<br>
|
|
381
|
-
📊 Generating insights...
|
|
382
|
-
</p>
|
|
383
|
-
`;
|
|
384
|
-
loadingOverlay.style.display = 'flex';
|
|
385
|
-
|
|
386
|
-
try {
|
|
387
|
-
// Prepare the data in the required format {"id":"description"}
|
|
388
|
-
const selectedFieldsObject = {};
|
|
389
|
-
selectedFields.forEach((description, fieldId) => {
|
|
390
|
-
selectedFieldsObject[fieldId] = description;
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
// Get Coze API configuration
|
|
394
|
-
const cozeApiToken = document.getElementById('cozeApiTokenInput').value;
|
|
395
|
-
const workflowId = document.getElementById('workflowIdInput').value;
|
|
396
|
-
|
|
397
|
-
// Validate inputs
|
|
398
|
-
if (!cozeApiToken) {
|
|
399
|
-
alert('Please enter a Coze API token');
|
|
400
|
-
document.getElementById('loadingOverlay').style.display = 'none';
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
if (!workflowId) {
|
|
405
|
-
alert('Please enter a Workflow ID');
|
|
406
|
-
document.getElementById('loadingOverlay').style.display = 'none';
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// Update loading message to show API call is happening
|
|
411
|
-
loadingContent.innerHTML = `
|
|
412
|
-
<h3>📡 Coze API Request in Progress...</h3>
|
|
413
|
-
<p>Workflow ID: ${workflowId}</p>
|
|
414
|
-
<p>Selected Fields: ${Object.keys(selectedFieldsObject).join(', ')}</p>
|
|
415
|
-
<p style="font-size: 14px; color: #4caf50; margin-top: 10px;">
|
|
416
|
-
✅ API credentials validated<br>
|
|
417
|
-
🔄 Sending request to Coze servers...<br>
|
|
418
|
-
⏳ Please wait for response...
|
|
419
|
-
</p>
|
|
420
|
-
`;
|
|
421
|
-
|
|
422
|
-
console.log('🚀 Starting Coze API request...');
|
|
423
|
-
console.log('📋 Selected fields:', selectedFieldsObject);
|
|
424
|
-
console.log('🔑 Using API token ending with:', cozeApiToken.slice(-10));
|
|
425
|
-
console.log('⚙️ Workflow ID:', workflowId);
|
|
426
|
-
|
|
427
|
-
// Call the process endpoint
|
|
428
|
-
const response = await fetch('/idea-house/api/process-fields', {
|
|
429
|
-
method: 'POST',
|
|
430
|
-
headers: {
|
|
431
|
-
'Content-Type': 'application/json'
|
|
432
|
-
},
|
|
433
|
-
body: JSON.stringify({
|
|
434
|
-
selected_fields: selectedFieldsObject,
|
|
435
|
-
coze_api_token: cozeApiToken,
|
|
436
|
-
workflow_id: workflowId,
|
|
437
|
-
dataset_description: window.currentDatasetDescription || ''
|
|
438
|
-
})
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
console.log('📡 Received response from server');
|
|
442
|
-
|
|
443
|
-
const result = await response.json();
|
|
444
|
-
|
|
445
|
-
if (!response.ok) {
|
|
446
|
-
console.error('❌ Coze API request failed:', result.error);
|
|
447
|
-
throw new Error(result.error || 'Failed to process fields');
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
console.log('✅ Coze API request successful!');
|
|
451
|
-
console.log('📊 Result:', result);
|
|
452
|
-
|
|
453
|
-
// Update loading message to show success
|
|
454
|
-
loadingContent.innerHTML = `
|
|
455
|
-
<h3>✅ Coze API Response Received!</h3>
|
|
456
|
-
<p style="color: #4caf50;">Successfully processed through workflow</p>
|
|
457
|
-
<p style="font-size: 14px; margin-top: 10px;">
|
|
458
|
-
📥 Response received from Coze<br>
|
|
459
|
-
🎉 Formatting results...
|
|
460
|
-
</p>
|
|
461
|
-
`;
|
|
462
|
-
|
|
463
|
-
// Small delay to show the success message
|
|
464
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
465
|
-
|
|
466
|
-
// Display results
|
|
467
|
-
displayResults(result);
|
|
468
|
-
|
|
469
|
-
} catch (error) {
|
|
470
|
-
console.error('💥 Failed to process fields via Coze API:', error);
|
|
471
|
-
alert(`Failed to process fields via Coze API: ${error.message}`);
|
|
472
|
-
} finally {
|
|
473
|
-
// Hide loading overlay
|
|
474
|
-
document.getElementById('loadingOverlay').style.display = 'none';
|
|
475
|
-
|
|
476
|
-
// Reset loading content for next time
|
|
477
|
-
loadingContent.innerHTML = `
|
|
478
|
-
<h3>Processing...</h3>
|
|
479
|
-
<p>Please wait while we analyze your selected fields...</p>
|
|
480
|
-
`;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
// Display results in markdown format
|
|
485
|
-
function displayResults(result) {
|
|
486
|
-
const resultsSection = document.getElementById('resultsSection');
|
|
487
|
-
const resultsContent = document.getElementById('resultsContent');
|
|
488
|
-
|
|
489
|
-
// Show results section
|
|
490
|
-
resultsSection.style.display = 'block';
|
|
491
|
-
|
|
492
|
-
// Format the results as markdown - simplified version
|
|
493
|
-
let markdown = '# Analysis Results\n\n';
|
|
494
|
-
|
|
495
|
-
// Add selected fields section
|
|
496
|
-
markdown += '## Selected Fields\n\n';
|
|
497
|
-
Object.entries(result.selected_fields).forEach(([fieldId, description]) => {
|
|
498
|
-
markdown += `- **${fieldId}**: ${description}\n`;
|
|
499
|
-
});
|
|
500
|
-
markdown += '\n';
|
|
501
|
-
|
|
502
|
-
// Add output section - only show the actual analysis output
|
|
503
|
-
markdown += '## Analysis Output\n\n';
|
|
504
|
-
if (result.output) {
|
|
505
|
-
// If the output is already formatted text, use it directly
|
|
506
|
-
if (typeof result.output === 'string') {
|
|
507
|
-
markdown += result.output;
|
|
508
|
-
} else {
|
|
509
|
-
// If it's an object, try to display it nicely
|
|
510
|
-
markdown += '```json\n';
|
|
511
|
-
markdown += JSON.stringify(result.output, null, 2);
|
|
512
|
-
markdown += '\n```\n';
|
|
513
|
-
}
|
|
514
|
-
} else {
|
|
515
|
-
markdown += '_No output data available_';
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
// Render the markdown as HTML
|
|
519
|
-
resultsContent.innerHTML = renderMarkdown(markdown);
|
|
520
|
-
|
|
521
|
-
// Scroll to results
|
|
522
|
-
resultsSection.scrollIntoView({ behavior: 'smooth' });
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// Helper function to format markdown (optional enhancement)
|
|
526
|
-
function renderMarkdown(markdown) {
|
|
527
|
-
// This is an improved markdown renderer that handles lists better
|
|
528
|
-
let html = markdown;
|
|
529
|
-
|
|
530
|
-
// First, escape HTML to prevent XSS
|
|
531
|
-
html = html.replace(/&/g, '&')
|
|
532
|
-
.replace(/</g, '<')
|
|
533
|
-
.replace(/>/g, '>');
|
|
534
|
-
|
|
535
|
-
// Code blocks (must be before inline code)
|
|
536
|
-
html = html.replace(/```([\s\S]*?)```/g, function(match, code) {
|
|
537
|
-
return '<pre><code>' + code.trim() + '</code></pre>';
|
|
538
|
-
});
|
|
539
|
-
|
|
540
|
-
// Headers
|
|
541
|
-
html = html.replace(/^#### (.*$)/gim, '<h4>$1</h4>');
|
|
542
|
-
html = html.replace(/^### (.*$)/gim, '<h3>$1</h3>');
|
|
543
|
-
html = html.replace(/^## (.*$)/gim, '<h2>$1</h2>');
|
|
544
|
-
html = html.replace(/^# (.*$)/gim, '<h1>$1</h1>');
|
|
545
|
-
|
|
546
|
-
// Bold (must be before italic)
|
|
547
|
-
html = html.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
|
|
548
|
-
|
|
549
|
-
// Italic
|
|
550
|
-
html = html.replace(/\*([^*\n]+)\*/g, '<em>$1</em>');
|
|
551
|
-
|
|
552
|
-
// Inline code
|
|
553
|
-
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
|
|
554
|
-
|
|
555
|
-
// Handle lists more carefully
|
|
556
|
-
// Split into lines for better list processing
|
|
557
|
-
const lines = html.split('\n');
|
|
558
|
-
let inList = false;
|
|
559
|
-
let processedLines = [];
|
|
560
|
-
|
|
561
|
-
for (let i = 0; i < lines.length; i++) {
|
|
562
|
-
let line = lines[i];
|
|
563
|
-
|
|
564
|
-
// Check if line is a list item
|
|
565
|
-
if (line.match(/^[\*\-\+] /)) {
|
|
566
|
-
// Replace list marker with proper HTML
|
|
567
|
-
line = line.replace(/^[\*\-\+] (.*)$/, '<li>$1</li>');
|
|
568
|
-
|
|
569
|
-
// If not in a list, start one
|
|
570
|
-
if (!inList) {
|
|
571
|
-
processedLines.push('<ul>');
|
|
572
|
-
inList = true;
|
|
573
|
-
}
|
|
574
|
-
processedLines.push(line);
|
|
575
|
-
} else if (line.match(/^\d+\. /)) {
|
|
576
|
-
// Ordered list
|
|
577
|
-
line = line.replace(/^\d+\. (.*)$/, '<li>$1</li>');
|
|
578
|
-
|
|
579
|
-
// If not in a list or previous was unordered, start ordered list
|
|
580
|
-
if (!inList || (i > 0 && lines[i-1].match(/^[\*\-\+] /))) {
|
|
581
|
-
if (inList) processedLines.push('</ul>');
|
|
582
|
-
processedLines.push('<ol>');
|
|
583
|
-
inList = true;
|
|
584
|
-
}
|
|
585
|
-
processedLines.push(line);
|
|
586
|
-
} else {
|
|
587
|
-
// Not a list item
|
|
588
|
-
if (inList) {
|
|
589
|
-
// Close the list
|
|
590
|
-
if (i > 0 && lines[i-1].match(/^\d+\. /)) {
|
|
591
|
-
processedLines.push('</ol>');
|
|
592
|
-
} else {
|
|
593
|
-
processedLines.push('</ul>');
|
|
594
|
-
}
|
|
595
|
-
inList = false;
|
|
596
|
-
}
|
|
597
|
-
processedLines.push(line);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// Close any remaining list
|
|
602
|
-
if (inList) {
|
|
603
|
-
if (lines[lines.length - 1].match(/^\d+\. /)) {
|
|
604
|
-
processedLines.push('</ol>');
|
|
605
|
-
} else {
|
|
606
|
-
processedLines.push('</ul>');
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
html = processedLines.join('\n');
|
|
611
|
-
|
|
612
|
-
// Line breaks - convert double newlines to paragraphs
|
|
613
|
-
html = html.replace(/\n\n/g, '</p><p>');
|
|
614
|
-
html = '<p>' + html + '</p>';
|
|
615
|
-
|
|
616
|
-
// Clean up empty paragraphs
|
|
617
|
-
html = html.replace(/<p>\s*<\/p>/g, '');
|
|
618
|
-
html = html.replace(/<p>(<h[1-6]>)/g, '$1');
|
|
619
|
-
html = html.replace(/(<\/h[1-6]>)<\/p>/g, '$1');
|
|
620
|
-
html = html.replace(/<p>(<ul>|<ol>|<pre>)/g, '$1');
|
|
621
|
-
html = html.replace(/(<\/ul>|<\/ol>|<\/pre>)<\/p>/g, '$1');
|
|
622
|
-
|
|
623
|
-
// Single line breaks within paragraphs
|
|
624
|
-
html = html.replace(/\n/g, '<br>');
|
|
625
|
-
|
|
626
|
-
return html;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
// Save Coze configuration to localStorage
|
|
630
|
-
function saveCozeConfig() {
|
|
631
|
-
const cozeApiToken = document.getElementById('cozeApiTokenInput').value;
|
|
632
|
-
const workflowId = document.getElementById('workflowIdInput').value;
|
|
633
|
-
|
|
634
|
-
// Save to localStorage
|
|
635
|
-
localStorage.setItem('coze_api_token', cozeApiToken);
|
|
636
|
-
localStorage.setItem('coze_workflow_id', workflowId);
|
|
637
|
-
|
|
638
|
-
// Show success message
|
|
639
|
-
const messageElement = document.getElementById('saveConfigMessage');
|
|
640
|
-
messageElement.style.display = 'inline';
|
|
641
|
-
|
|
642
|
-
// Hide message after 3 seconds
|
|
643
|
-
setTimeout(() => {
|
|
644
|
-
messageElement.style.display = 'none';
|
|
645
|
-
}, 3000);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
// Load saved Coze configuration from localStorage
|
|
649
|
-
function loadSavedCozeConfig() {
|
|
650
|
-
const savedToken = localStorage.getItem('coze_api_token');
|
|
651
|
-
const savedWorkflowId = localStorage.getItem('coze_workflow_id');
|
|
652
|
-
|
|
653
|
-
if (savedToken) {
|
|
654
|
-
document.getElementById('cozeApiTokenInput').value = savedToken;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
if (savedWorkflowId) {
|
|
658
|
-
document.getElementById('workflowIdInput').value = savedWorkflowId;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// Clear Coze configuration and reset to defaults
|
|
663
|
-
function clearCozeConfig() {
|
|
664
|
-
// Remove from localStorage
|
|
665
|
-
localStorage.removeItem('coze_api_token');
|
|
666
|
-
localStorage.removeItem('coze_workflow_id');
|
|
667
|
-
|
|
668
|
-
// Reset to default values
|
|
669
|
-
document.getElementById('cozeApiTokenInput').value = 'pat_OCxUpnmL7hCvUxEWwcKL5XwUOdoiA3eWLzwY6L8W9sQVN1saJnoMrDNyhFhEn63l';
|
|
670
|
-
document.getElementById('workflowIdInput').value = '7522912027267956786';
|
|
671
|
-
|
|
672
|
-
// Show message
|
|
673
|
-
const messageElement = document.getElementById('saveConfigMessage');
|
|
674
|
-
messageElement.textContent = 'Configuration reset to default!';
|
|
675
|
-
messageElement.style.color = '#ff9800';
|
|
676
|
-
messageElement.style.display = 'inline';
|
|
677
|
-
|
|
678
|
-
// Hide message after 3 seconds
|
|
679
|
-
setTimeout(() => {
|
|
680
|
-
messageElement.style.display = 'none';
|
|
681
|
-
messageElement.textContent = 'Configuration saved!';
|
|
682
|
-
messageElement.style.color = '#4caf50';
|
|
683
|
-
}, 3000);
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// Set up filter event listeners
|
|
687
|
-
function setupFilterEventListeners() {
|
|
688
|
-
// Quick filter checkboxes
|
|
689
|
-
const highCoverageFilter = document.getElementById('filterHighCoverage');
|
|
690
|
-
const popularFilter = document.getElementById('filterPopular');
|
|
691
|
-
const matrixOnlyFilter = document.getElementById('filterMatrixOnly');
|
|
692
|
-
|
|
693
|
-
// Filter action buttons
|
|
694
|
-
const selectAllBtn = document.getElementById('selectAllFiltered');
|
|
695
|
-
const clearAllBtn = document.getElementById('clearAllSelected');
|
|
696
|
-
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
|
|
697
|
-
|
|
698
|
-
// Set up quick filter listeners
|
|
699
|
-
if (highCoverageFilter) highCoverageFilter.onchange = () => populateDataFieldsTable();
|
|
700
|
-
if (popularFilter) popularFilter.onchange = () => populateDataFieldsTable();
|
|
701
|
-
if (matrixOnlyFilter) matrixOnlyFilter.onchange = () => populateDataFieldsTable();
|
|
702
|
-
|
|
703
|
-
// Set up action button listeners
|
|
704
|
-
if (selectAllBtn) selectAllBtn.onclick = selectAllFilteredFields;
|
|
705
|
-
if (clearAllBtn) clearAllBtn.onclick = clearAllSelectedFields;
|
|
706
|
-
|
|
707
|
-
if (selectAllCheckbox) {
|
|
708
|
-
selectAllCheckbox.onclick = (e) => {
|
|
709
|
-
e.stopPropagation();
|
|
710
|
-
if (selectAllCheckbox.checked) {
|
|
711
|
-
selectAllFilteredFields();
|
|
712
|
-
} else {
|
|
713
|
-
clearAllFilteredFields();
|
|
714
|
-
}
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
// Column filter listeners
|
|
719
|
-
document.querySelectorAll('.column-filter').forEach(filter => {
|
|
720
|
-
filter.addEventListener('input', (e) => {
|
|
721
|
-
const column = e.target.dataset.column;
|
|
722
|
-
const value = e.target.value;
|
|
723
|
-
|
|
724
|
-
if (column === 'userCount' || column === 'alphaCount') {
|
|
725
|
-
columnFilters[column] = value ? parseInt(value) : null;
|
|
726
|
-
} else {
|
|
727
|
-
columnFilters[column] = value;
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
// Add/remove active class
|
|
731
|
-
if (value) {
|
|
732
|
-
e.target.classList.add('active');
|
|
733
|
-
} else {
|
|
734
|
-
e.target.classList.remove('active');
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
populateDataFieldsTable();
|
|
738
|
-
});
|
|
739
|
-
});
|
|
740
|
-
|
|
741
|
-
// Coverage range filters
|
|
742
|
-
document.querySelectorAll('.column-filter-min, .column-filter-max').forEach(filter => {
|
|
743
|
-
filter.addEventListener('input', (e) => {
|
|
744
|
-
const isMin = e.target.classList.contains('column-filter-min');
|
|
745
|
-
const value = e.target.value;
|
|
746
|
-
|
|
747
|
-
if (isMin) {
|
|
748
|
-
columnFilters.coverage.min = value ? parseFloat(value) : null;
|
|
749
|
-
} else {
|
|
750
|
-
columnFilters.coverage.max = value ? parseFloat(value) : null;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
// Add/remove active class
|
|
754
|
-
const minInput = e.target.parentElement.querySelector('.column-filter-min');
|
|
755
|
-
const maxInput = e.target.parentElement.querySelector('.column-filter-max');
|
|
756
|
-
|
|
757
|
-
if (minInput.value || maxInput.value) {
|
|
758
|
-
minInput.classList.add('active');
|
|
759
|
-
maxInput.classList.add('active');
|
|
760
|
-
} else {
|
|
761
|
-
minInput.classList.remove('active');
|
|
762
|
-
maxInput.classList.remove('active');
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
populateDataFieldsTable();
|
|
766
|
-
});
|
|
767
|
-
});
|
|
768
|
-
|
|
769
|
-
// Sort button listeners
|
|
770
|
-
document.querySelectorAll('.sort-btn').forEach(btn => {
|
|
771
|
-
btn.addEventListener('click', (e) => {
|
|
772
|
-
const column = e.target.dataset.column;
|
|
773
|
-
|
|
774
|
-
// Reset all other sort buttons
|
|
775
|
-
document.querySelectorAll('.sort-btn').forEach(b => {
|
|
776
|
-
if (b !== e.target) {
|
|
777
|
-
b.classList.remove('asc', 'desc');
|
|
778
|
-
b.dataset.order = 'asc';
|
|
779
|
-
}
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
// Toggle sort order
|
|
783
|
-
if (sortColumn === column) {
|
|
784
|
-
sortOrder = sortOrder === 'asc' ? 'desc' : 'asc';
|
|
785
|
-
} else {
|
|
786
|
-
sortColumn = column;
|
|
787
|
-
sortOrder = 'asc';
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
e.target.dataset.order = sortOrder;
|
|
791
|
-
e.target.classList.remove('asc', 'desc');
|
|
792
|
-
e.target.classList.add(sortOrder);
|
|
793
|
-
|
|
794
|
-
populateDataFieldsTable();
|
|
795
|
-
});
|
|
796
|
-
});
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
// Update data fields statistics
|
|
800
|
-
function updateDataFieldsStats() {
|
|
801
|
-
const dataFieldsCountEl = document.getElementById('dataFieldsCount');
|
|
802
|
-
const filteredCountEl = document.getElementById('filteredCount');
|
|
803
|
-
const selectedCountEl = document.getElementById('selectedFieldsCount');
|
|
804
|
-
|
|
805
|
-
if (dataFieldsCountEl) dataFieldsCountEl.textContent = `${dataFields.length} fields loaded`;
|
|
806
|
-
if (filteredCountEl) filteredCountEl.textContent = `${filteredDataFields.length} filtered`;
|
|
807
|
-
if (selectedCountEl) selectedCountEl.textContent = `${selectedFields.size} selected`;
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
// Populate type filter dropdown
|
|
811
|
-
function populateTypeFilter() {
|
|
812
|
-
const typeFilter = document.getElementById('typeFilter');
|
|
813
|
-
if (!typeFilter) return;
|
|
814
|
-
|
|
815
|
-
// Get unique types from current data fields
|
|
816
|
-
const uniqueTypes = [...new Set(dataFields.map(field => field.type))].sort();
|
|
817
|
-
|
|
818
|
-
// Clear existing options except "All Types"
|
|
819
|
-
typeFilter.innerHTML = '<option value="">All Types</option>';
|
|
820
|
-
|
|
821
|
-
uniqueTypes.forEach(type => {
|
|
822
|
-
const option = document.createElement('option');
|
|
823
|
-
option.value = type;
|
|
824
|
-
option.textContent = type;
|
|
825
|
-
typeFilter.appendChild(option);
|
|
826
|
-
});
|
|
827
|
-
|
|
828
|
-
// Restore selected value if it exists
|
|
829
|
-
if (columnFilters.type && uniqueTypes.includes(columnFilters.type)) {
|
|
830
|
-
typeFilter.value = columnFilters.type;
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
// Select all filtered fields
|
|
835
|
-
function selectAllFilteredFields() {
|
|
836
|
-
filteredDataFields.forEach(field => {
|
|
837
|
-
selectedFields.set(field.id, field.description);
|
|
838
|
-
const row = document.querySelector(`tr[data-field-id="${field.id}"]`);
|
|
839
|
-
if (row) {
|
|
840
|
-
const checkbox = row.querySelector('.field-checkbox');
|
|
841
|
-
checkbox.checked = true;
|
|
842
|
-
row.classList.add('selected');
|
|
843
|
-
}
|
|
844
|
-
});
|
|
845
|
-
|
|
846
|
-
updateSelectedFieldsDisplay();
|
|
847
|
-
updateDataFieldsStats();
|
|
848
|
-
updateSelectAllCheckbox();
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
// Clear all selected fields
|
|
852
|
-
function clearAllSelectedFields() {
|
|
853
|
-
selectedFields.clear();
|
|
854
|
-
|
|
855
|
-
// Update all checkboxes
|
|
856
|
-
document.querySelectorAll('.field-checkbox').forEach(checkbox => {
|
|
857
|
-
checkbox.checked = false;
|
|
858
|
-
checkbox.closest('tr').classList.remove('selected');
|
|
859
|
-
});
|
|
860
|
-
|
|
861
|
-
updateSelectedFieldsDisplay();
|
|
862
|
-
updateDataFieldsStats();
|
|
863
|
-
updateSelectAllCheckbox();
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
// Clear only filtered fields
|
|
867
|
-
function clearAllFilteredFields() {
|
|
868
|
-
filteredDataFields.forEach(field => {
|
|
869
|
-
selectedFields.delete(field.id);
|
|
870
|
-
const row = document.querySelector(`tr[data-field-id="${field.id}"]`);
|
|
871
|
-
if (row) {
|
|
872
|
-
const checkbox = row.querySelector('.field-checkbox');
|
|
873
|
-
checkbox.checked = false;
|
|
874
|
-
row.classList.remove('selected');
|
|
875
|
-
}
|
|
876
|
-
});
|
|
877
|
-
|
|
878
|
-
updateSelectedFieldsDisplay();
|
|
879
|
-
updateDataFieldsStats();
|
|
880
|
-
updateSelectAllCheckbox();
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
// Update the select all checkbox state
|
|
884
|
-
function updateSelectAllCheckbox() {
|
|
885
|
-
const selectAllCheckbox = document.getElementById('selectAllCheckbox');
|
|
886
|
-
if (!selectAllCheckbox) return;
|
|
887
|
-
|
|
888
|
-
const allFilteredSelected = filteredDataFields.length > 0 &&
|
|
889
|
-
filteredDataFields.every(field => selectedFields.has(field.id));
|
|
890
|
-
|
|
891
|
-
selectAllCheckbox.checked = allFilteredSelected;
|
|
892
|
-
selectAllCheckbox.indeterminate = !allFilteredSelected &&
|
|
893
|
-
filteredDataFields.some(field => selectedFields.has(field.id));
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
// Display dataset description
|
|
897
|
-
function displayDatasetDescription(description) {
|
|
898
|
-
console.log('🎨 Displaying dataset description:', description);
|
|
899
|
-
|
|
900
|
-
// Check if dataset description element already exists
|
|
901
|
-
let descriptionElement = document.getElementById('datasetDescription');
|
|
902
|
-
|
|
903
|
-
if (!descriptionElement) {
|
|
904
|
-
console.log('📌 Creating new dataset description element');
|
|
905
|
-
|
|
906
|
-
// Create the element if it doesn't exist
|
|
907
|
-
const tableContainer = document.getElementById('tableContainer');
|
|
908
|
-
const dataFieldsControls = tableContainer.querySelector('.data-fields-controls');
|
|
909
|
-
|
|
910
|
-
// Create a new div for the dataset description
|
|
911
|
-
descriptionElement = document.createElement('div');
|
|
912
|
-
descriptionElement.id = 'datasetDescription';
|
|
913
|
-
descriptionElement.className = 'dataset-description';
|
|
914
|
-
descriptionElement.style.cssText = `
|
|
915
|
-
padding: 15px;
|
|
916
|
-
background: #e8f5e9;
|
|
917
|
-
border: 1px solid #4caf50;
|
|
918
|
-
border-radius: 4px;
|
|
919
|
-
margin-bottom: 15px;
|
|
920
|
-
font-size: 14px;
|
|
921
|
-
line-height: 1.5;
|
|
922
|
-
`;
|
|
923
|
-
|
|
924
|
-
// Insert it before the controls
|
|
925
|
-
tableContainer.insertBefore(descriptionElement, dataFieldsControls);
|
|
926
|
-
console.log('✅ Dataset description element created and inserted');
|
|
927
|
-
} else {
|
|
928
|
-
console.log('📌 Using existing dataset description element');
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
// Update the content
|
|
932
|
-
descriptionElement.innerHTML = `
|
|
933
|
-
<strong>Dataset Description:</strong><br>
|
|
934
|
-
${description}
|
|
935
|
-
`;
|
|
936
|
-
console.log('✅ Dataset description content updated');
|
|
937
|
-
}
|