// Array to store problem history versions
const problemHistory = [];
let currentHistoryIndex = -1;
// Store all refined problem suggestions
let storedRefinedProblems = {};
// function generateQueries(event) {
// event.preventDefault();
// const userInput = document.getElementById('userInput').value.trim();
// if (!userInput) {
// alert('Please enter a technical problem description');
// return;
// }
// // Show loading indicator
// document.getElementById('loadingIndicator').style.display = 'block';
// // Send message to Flask backend
// fetch('/generate-key-issues', {
// method: 'POST',
// body: JSON.stringify({ 'query': userInput }),
// headers: { 'Content-Type': 'application/json' }
// })
// .then(response => response.json())
// .then(data => {
// // Hide loading indicator
// document.getElementById('loadingIndicator').style.display = 'none';
// // Check if we have key issues in the response
// if (data.key_issues && data.key_issues.length > 0) {
// // Display the key issues
// displayKeyIssues(data.key_issues);
// } else if (data.error) {
// alert('Error: ' + data.error);
// } else {
// alert('No key issues found. Please try a different query.');
// }
// })
// .catch(error => {
// document.getElementById('loadingIndicator').style.display = 'none';
// console.error('Error:', error);
// alert('There was an error communicating with the server. Please try again.');
// });
// }
function displayKeyIssues(keyIssues) {
// Get or create the key issues container
let keyIssuesContainer = document.getElementById('keyIssuesContainer');
if (!keyIssuesContainer) {
keyIssuesContainer = document.createElement('div');
keyIssuesContainer.id = 'keyIssuesContainer';
keyIssuesContainer.className = 'key-issues-container';
document.getElementById('resultsContainer').appendChild(keyIssuesContainer);
}
// Clear previous content
keyIssuesContainer.innerHTML = '';
// Create header
const header = document.createElement('h3');
header.textContent = 'Key Issues';
keyIssuesContainer.appendChild(header);
// Create issues list
const issuesList = document.createElement('div');
issuesList.className = 'key-issues-list';
// Add each key issue
keyIssues.forEach(issue => {
const issueCard = document.createElement('div');
issueCard.className = 'key-issue-card';
issueCard.dataset.id = issue.id;
const issueTitle = document.createElement('div');
issueTitle.className = 'key-issue-title';
issueTitle.textContent = issue.title;
const issueDescription = document.createElement('div');
issueDescription.className = 'key-issue-description';
issueDescription.textContent = issue.description;
const challengesTitle = document.createElement('div');
challengesTitle.style.fontWeight = 'bold';
challengesTitle.style.marginTop = '10px';
challengesTitle.textContent = 'Challenges:';
const challengesList = document.createElement('div');
challengesList.className = 'key-issue-challenges';
issue.challenges.forEach(challenge => {
const challengeTag = document.createElement('div');
challengeTag.className = 'challenge-tag';
challengeTag.textContent = challenge;
// Add click handler to toggle selection
challengeTag.addEventListener('click', function(e) {
e.stopPropagation(); // Prevent triggering parent card click
this.classList.toggle('selected');
// Update selected challenges data
const selectedChallenges = JSON.parse(issueCard.dataset.selectedChallenges || '[]');
const challengeText = this.textContent;
if (this.classList.contains('selected')) {
// Add challenge to selected list if not already there
if (!selectedChallenges.includes(challengeText)) {
selectedChallenges.push(challengeText);
}
} else {
// Remove challenge from selected list
const index = selectedChallenges.indexOf(challengeText);
if (index !== -1) {
selectedChallenges.splice(index, 1);
}
}
// Update dataset
issueCard.dataset.selectedChallenges = JSON.stringify(selectedChallenges);
// Update card selected state based on whether any challenges are selected
if (selectedChallenges.length > 0) {
issueCard.classList.add('selected');
// Add to selected key issues if not already there
if (!selectedKeyIssues.some(item => item.id === issue.id)) {
selectedKeyIssues.push(issue);
}
} else {
issueCard.classList.remove('selected');
// Remove from selected key issues
selectedKeyIssues = selectedKeyIssues.filter(item => item.id !== issue.id);
}
// Update the comment area based on selections
updateCommentArea();
});
challengesList.appendChild(challengeTag);
});
const impactTitle = document.createElement('div');
impactTitle.style.fontWeight = 'bold';
impactTitle.style.marginTop = '10px';
impactTitle.textContent = 'Potential Impact:';
const issueImpact = document.createElement('div');
issueImpact.className = 'key-issue-impact';
issueImpact.textContent = issue.potential_impact;
// No direct click handler on issue cards - they only get selected through challenge selection
// Initialize the dataset.selectedChallenges array
issueCard.dataset.selectedChallenges = JSON.stringify([]);
// Append all elements
issueCard.appendChild(issueTitle);
issueCard.appendChild(issueDescription);
issueCard.appendChild(challengesTitle);
issueCard.appendChild(challengesList);
issueCard.appendChild(impactTitle);
issueCard.appendChild(issueImpact);
issuesList.appendChild(issueCard);
});
keyIssuesContainer.appendChild(issuesList);
// Create API submit button (floating style)
const apiSubmitButton = document.createElement('button');
apiSubmitButton.id = 'generatePriorArtButton';
apiSubmitButton.className = 'btn btn-primary floating-button';
apiSubmitButton.textContent = 'Generate Prior Art';
apiSubmitButton.style.backgroundColor = '#10b981'; // Green color to differentiate
apiSubmitButton.style.color = 'white';
apiSubmitButton.addEventListener('click', submitSelectedKeyIssuesToAPI);
// Add to floating buttons container
document.querySelector('.floating-buttons').appendChild(apiSubmitButton);
// Show the results container
document.getElementById('resultsContainer').style.display = 'block';
}
// Function to submit selected key issues to the API
function submitSelectedKeyIssuesToAPI() {
const userInput = document.getElementById('userInput').value.trim();
if (!userInput) {
alert('Please provide a technical problem description');
return;
}
// Find all key issue cards with selected challenges
const issueCards = document.querySelectorAll('.key-issue-card');
const keyIssuesData = [];
issueCards.forEach(card => {
const selectedChallenges = JSON.parse(card.dataset.selectedChallenges || '[]');
// Only include issues with at least one selected challenge
if (selectedChallenges.length > 0) {
const issueDescription = card.querySelector('.key-issue-description').textContent;
keyIssuesData.push({
"description": issueDescription,
"challenges": selectedChallenges
});
}
});
// If no key issues with selected challenges, show message
if (keyIssuesData.length === 0) {
alert('Please select at least one challenge in a key issue');
return;
}
// Create or update API response container with loading message - using refined problem container style
let apiResponseContainer = document.getElementById('apiResponseContainer');
if (!apiResponseContainer) {
apiResponseContainer = document.createElement('div');
apiResponseContainer.id = 'apiResponseContainer';
apiResponseContainer.className = 'refined-problem-container';
document.getElementById('resultsContainer').appendChild(apiResponseContainer);
}
// Set loading message
apiResponseContainer.innerHTML = `
Processing
Generating prior art based on selected key issues and challenges. This may take a moment...
`;
// Show the container and scroll to it
apiResponseContainer.style.display = 'block';
apiResponseContainer.scrollIntoView({ behavior: 'smooth' });
// Prepare the payload
const payload = {
"keys_issues": keyIssuesData,
"technical_topic": userInput
};
console.log('Sending data to API:', JSON.stringify(payload, null, 2));
// Send data to API
fetch('/generate-prior-art', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload)
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('API Response:', data);
// For testing, we can use a mock response based on the example format
// Remove this in production
if (!data || (Array.isArray(data) && data.length === 0)) {
console.log('Using mock data for testing');
data = [
{
"problem_description": "I am working on managing conflicting instructions for network behavior in 5G systems. The core problem is how to ensure that requests coming dynamically from applications serving critical functions are reliably given higher priority and override the static network settings stored in a user's plan. This requires a solution that addresses the security risks associated with allowing applications to dictate network treatment and ensures this rule is enforced uniformly across the central network components.",
"problematic": "How can 5G core network functions securely and reliably enforce dynamic network treatment instructions from critical function applications, ensuring they consistently override conflicting static policy configurations derived from user plans, while uniformly mitigating the security risks associated with application-level control over network behavior?",
"score": 0.845
},
{
"problem_description": "I am working on enhancing security in 5G networks, specifically related to how network segments are configured based on user profiles. My goal is to address the security risks that arise when requests from external applications conflict with the priority settings defined in a user's profile for essential services, ensuring that unauthorized changes to service priority are securely prevented and handled throughout the core network.",
"problematic": "How can security risks arising from external application requests conflicting with user profile-defined priority settings for essential services in 5G networks be securely mitigated, ensuring that unauthorized modifications to service priority are effectively prevented and managed throughout the core network segments configured based on these profiles?",
"score": 0.624
},
{
"problem_description": "I am working on managing conflicting instructions for network behavior in 5G systems. The core problem is how to ensure that requests coming dynamically from applications serving critical functions are reliably given higher priority and override the static network settings stored in a user's plan. This requires a solution that addresses the security risks associated with allowing applications to dictate network treatment and ensures this rule is enforced uniformly across the central network components.",
"problematic": "How can 5G core network functions securely and reliably enforce dynamic network treatment instructions from critical function applications, ensuring they consistently override conflicting static policy configurations derived from user plans, while uniformly mitigating the security risks associated with application-level control over network behavior?",
"score": 0.312
},
{
"problem_description": "I am working on enhancing security in 5G networks, specifically related to how network segments are configured based on user profiles. My goal is to address the security risks that arise when requests from external applications conflict with the priority settings defined in a user's profile for essential services, ensuring that unauthorized changes to service priority are securely prevented and handled throughout the core network.",
"problematic": "How can security risks arising from external application requests conflicting with user profile-defined priority settings for essential services in 5G networks be securely mitigated, ensuring that unauthorized modifications to service priority are effectively prevented and managed throughout the core network segments configured based on these profiles?",
"score": 0.305
}
];
}
// Display the API response
displayAPIResponse(data);
})
.catch(error => {
console.error('Error submitting to API:', error);
// Display error message in the API response container
apiResponseContainer.innerHTML = `
Error
Error Generating Prior Art
There was an error communicating with the API: ${error.message}
Please try again later or contact support.
`;
});
}
// Function to display the API response in a tabbed format
function displayAPIResponse(data) {
// Get or create container for API response
let apiResponseContainer = document.getElementById('apiResponseContainer');
if (!apiResponseContainer) {
apiResponseContainer = document.createElement('div');
apiResponseContainer.id = 'apiResponseContainer';
apiResponseContainer.className = 'refined-problem-container'; // Use the same style as refined problems
document.getElementById('resultsContainer').appendChild(apiResponseContainer);
}
// Clear previous content
apiResponseContainer.innerHTML = '';
// Create tabs and content containers similar to refined problems
const tabs = document.createElement('div');
tabs.className = 'refined-problem-tabs';
apiResponseContainer.appendChild(tabs);
const content = document.createElement('div');
content.className = 'refined-problem-content';
apiResponseContainer.appendChild(content);
try {
// Parse the data if it's a string
const problems = Array.isArray(data) ? data :
(typeof data === 'string' ? JSON.parse(data) :
(data.result || data.results || []));
// Sort problems by score in descending order
problems.sort((a, b) => (b.score || 0) - (a.score || 0));
// Add tabs and content for each problem
problems.forEach((problem, index) => {
const key = `problem_${index + 1}`;
const isFirst = index === 0;
// Create tab
const tab = document.createElement('div');
tab.className = `refined-problem-tab ${isFirst ? 'active' : ''}`;
tab.dataset.target = key;
// Format score as percentage
const score = typeof problem.score === 'number' ?
Math.round(problem.score * 100) :
'N/A';
tab.textContent = `Option ${index + 1} (${score}%)`;
tab.onclick = function() {
document.querySelectorAll('.refined-problem-tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.refined-problem').forEach(p => p.classList.remove('active'));
tab.classList.add('active');
document.getElementById(key).classList.add('active');
};
tabs.appendChild(tab);
// Create content
const problemDiv = document.createElement('div');
problemDiv.className = `refined-problem ${isFirst ? 'active' : ''}`;
problemDiv.id = key;
// Problem title (using problematic as title)
const title = document.createElement('div');
title.className = 'refined-problem-title';
title.textContent = problem.problematic || 'Alternative Problem Statement';
// Problem description
const description = document.createElement('div');
description.className = 'refined-problem-description';
description.textContent = problem.problem_description || problem.description || '';
// Apply button
const applyButton = document.createElement('button');
applyButton.className = 'apply-problem-btn';
applyButton.textContent = 'Apply This Problem';
applyButton.onclick = function() {
// Use the existing applyRefinedProblem function
applyRefinedProblem(problem.problem_description || problem.description || '');
};
// Add all elements to the problem div
problemDiv.appendChild(title);
problemDiv.appendChild(description);
problemDiv.appendChild(applyButton);
content.appendChild(problemDiv);
});
// If no problems found, display a message
if (problems.length === 0) {
const noResultsDiv = document.createElement('div');
noResultsDiv.className = 'refined-problem active';
noResultsDiv.textContent = 'No problem alternatives were generated. Please try again.';
content.appendChild(noResultsDiv);
}
} catch (error) {
console.error('Error displaying API response:', error);
// Display error message
const errorDiv = document.createElement('div');
errorDiv.className = 'refined-problem active';
errorDiv.innerHTML = `
Error
There was an error processing the API response: ${error.message}
`;
content.appendChild(errorDiv);
}
// Show the container
apiResponseContainer.style.display = 'block';
// Scroll to the container
apiResponseContainer.scrollIntoView({ behavior: 'smooth' });
}
// Add a new query field with the given text (or empty if not provided)
function addQueryField(queryText = '', container = null) {
const queriesContainer = container || document.getElementById('queriesContainer');
// Count existing query items in this container for indexing
const queryItems = container ?
container.querySelectorAll('.query-item') :
document.getElementById('queriesContainer').querySelectorAll('.query-item');
const queryIndex = queryItems.length + 1;
// Create main container for this query item
const queryItem = document.createElement('div');
queryItem.className = 'query-item';
// Create container for query field and buttons
const queryContainer = document.createElement('div');
queryContainer.className = 'query-container';
// Input field
const queryField = document.createElement('input');
queryField.type = 'text';
queryField.className = 'query-field';
queryField.value = queryText;
queryField.placeholder = `Search Query ${queryIndex}`;
// Delete button
const deleteButton = document.createElement('button');
deleteButton.type = 'button';
deleteButton.className = 'action-button delete-button';
deleteButton.textContent = 'Delete';
deleteButton.onclick = function() {
queryItem.parentNode.removeChild(queryItem);
// Update the placeholder numbers for remaining queries within this container
const parent = container || document.getElementById('queriesContainer');
const items = parent.querySelectorAll('.query-item');
items.forEach((item, idx) => {
const field = item.querySelector('.query-field');
if (field) field.placeholder = `Search Query ${idx + 1}`;
});
};
// Search button
const searchButton = document.createElement('button');
searchButton.type = 'button';
searchButton.className = 'action-button search-button';
searchButton.textContent = 'Search';
searchButton.onclick = function() {
performSearch(queryField.value, queryItem);
};
// Add elements to container
queryContainer.appendChild(queryField);
queryContainer.appendChild(searchButton);
queryContainer.appendChild(deleteButton);
// Create loading indicator for this search
const searchLoading = document.createElement('div');
searchLoading.className = 'search-loading';
searchLoading.textContent = 'Searching... Please wait.';
// Create table for results
const resultsTable = document.createElement('table');
resultsTable.className = 'results-table';
// Add table header
const tableHeader = document.createElement('thead');
const headerRow = document.createElement('tr');
const typeHeader = document.createElement('th');
typeHeader.textContent = 'Type';
const titleHeader = document.createElement('th');
titleHeader.textContent = 'Title';
const bodyHeader = document.createElement('th');
bodyHeader.textContent = 'Description';
const urlHeader = document.createElement('th');
urlHeader.textContent = 'URL';
const scoreHeader = document.createElement('th');
scoreHeader.textContent = 'Score';
const justificationHeader = document.createElement('th');
justificationHeader.textContent = 'Justification';
headerRow.appendChild(typeHeader);
headerRow.appendChild(titleHeader);
headerRow.appendChild(bodyHeader);
headerRow.appendChild(urlHeader);
headerRow.appendChild(scoreHeader);
headerRow.appendChild(justificationHeader);
tableHeader.appendChild(headerRow);
// Add table body
const tableBody = document.createElement('tbody');
resultsTable.appendChild(tableHeader);
resultsTable.appendChild(tableBody);
// Add all elements to the query item
queryItem.appendChild(queryContainer);
queryItem.appendChild(searchLoading);
queryItem.appendChild(resultsTable);
// Add container to the queries list
queriesContainer.appendChild(queryItem);
}
// Perform search and update the results table
function performSearch(query, queryItemElement) {
if (!query.trim()) {
alert('Please enter a search query');
return;
}
const loadingElement = queryItemElement.querySelector('.search-loading');
const tableElement = queryItemElement.querySelector('.results-table');
const tableBody = tableElement.querySelector('tbody');
// Show loading and hide previous results
loadingElement.style.display = 'block';
tableElement.style.display = 'none';
// Clear previous results
tableBody.innerHTML = '';
// Get checkbox values
const pdfChecked = document.getElementById('pdfOption').checked;
const patentChecked = document.getElementById('patentOption').checked;
const webChecked = document.getElementById('webOption').checked;
// Create form data with query and checkbox values
const formData = new FormData();
formData.append('query', query);
formData.append('pdfOption', pdfChecked);
formData.append('patentOption', patentChecked);
formData.append('webOption', webChecked);
// Send search request to backend
fetch('/search', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
// Hide loading indicator
loadingElement.style.display = 'none';
if (data.results && data.results.length > 0) {
// Populate table with results
data.results.forEach(result => {
const row = document.createElement('tr');
const typeCell = document.createElement('td');
typeCell.textContent = result.type;
const titleCell = document.createElement('td');
titleCell.textContent = result.title;
const bodyCell = document.createElement('td');
bodyCell.textContent = result.body;
const urlCell = document.createElement('td');
const urlLink = document.createElement('a');
urlLink.href = result.url;
urlLink.textContent = result.url;
urlLink.className = 'url-link';
urlLink.target = '_blank';
urlCell.appendChild(urlLink);
// Add "Analyze" button to the URL cell
const analyzeButton = document.createElement('button');
analyzeButton.textContent = 'Analyze';
analyzeButton.className = 'action-button analyze-button';
analyzeButton.onclick = function(e) {
e.preventDefault();
analyzePaper(result.url, queryItemElement);
};
urlCell.appendChild(document.createElement('br'));
urlCell.appendChild(analyzeButton);
row.appendChild(typeCell);
row.appendChild(titleCell);
row.appendChild(bodyCell);
row.appendChild(urlCell);
tableBody.appendChild(row);
});
// Show the table
tableElement.style.display = 'table';
} else {
// No results
const row = document.createElement('tr');
const cell = document.createElement('td');
cell.colSpan = 4; // Updated to 4 since we now have 4 columns with the type column
cell.textContent = 'No results found.';
cell.style.textAlign = 'center';
row.appendChild(cell);
tableBody.appendChild(row);
tableElement.style.display = 'table';
}
})
.catch(error => {
loadingElement.style.display = 'none';
console.error('Error:', error);
// Show error in table
const row = document.createElement('tr');
const cell = document.createElement('td');
cell.colSpan = 4; // Updated to 4 since we now have 4 columns with the type column
cell.textContent = 'Error performing search. Please try again.';
cell.style.textAlign = 'center';
cell.style.color = 'red';
row.appendChild(cell);
tableBody.appendChild(row);
tableElement.style.display = 'table';
});
}
// Extract insights from document
function extractInsights(paperUrl, row) {
const patentBackground = document.getElementById('userInput').value.trim();
if (!patentBackground) {
alert('Please provide a patent background in the input field');
return;
}
const documentType = row.cells[0].textContent.toLowerCase();
// Check if there's already an insights row for this document
let insightsRow = row.nextElementSibling;
if (insightsRow && insightsRow.className === 'insights-row') {
// Insights row already exists, get the container
insightsContainer = insightsRow.querySelector('.insights-container');
insightsContainer.innerHTML = '
';
insightsTd.appendChild(insightsContainer);
insightsRow.appendChild(insightsTd);
// Insert after the current row
row.parentNode.insertBefore(insightsRow, row.nextSibling);
}
// Store the row reference as a data attribute on the container for later access
insightsContainer.dataset.parentRow = row.rowIndex;
// Send request to extract insights
fetch('/post_insights', {
method: 'POST',
body: JSON.stringify({
'patent_background': patentBackground,
'pdf_url': paperUrl,
'data_type': documentType
}),
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
if (data.error) {
insightsContainer.innerHTML = `
Error: ${data.error}
`;
} else if (data.result && data.result.insights) {
// Create header with title and actions
const insightsHeader = document.createElement('div');
insightsHeader.className = 'insights-header';
const insightsTitle = document.createElement('div');
insightsTitle.className = 'insights-title';
insightsTitle.textContent = 'Document Insights';
const insightsActions = document.createElement('div');
insightsActions.className = 'insights-actions';
// Store the insights for this specific container
const containerInsights = [...data.result.insights];
insightsContainer.dataset.allInsights = JSON.stringify(containerInsights);
const selectAllBtn = document.createElement('button');
selectAllBtn.className = 'insights-button select-all-btn';
selectAllBtn.textContent = 'Select All';
// Use a closure to ensure the button has access to the correct container and row
selectAllBtn.addEventListener('click', function() {
const container = this.closest('.insights-container');
const parentRow = row;
const allInsights = JSON.parse(container.dataset.allInsights || '[]');
const tags = container.querySelectorAll('.insight-tag');
tags.forEach(tag => tag.classList.add('selected'));
parentRow.dataset.selectedInsights = JSON.stringify(allInsights);
parentRow.dataset.unselectedInsights = JSON.stringify([]);
// Trigger check for enabling/disabling enhance button
checkSelectedInsights();
});
const clearAllBtn = document.createElement('button');
clearAllBtn.className = 'insights-button clear-all-btn';
clearAllBtn.textContent = 'Clear All';
// Use a closure to ensure the button has access to the correct container and row
clearAllBtn.addEventListener('click', function() {
const container = this.closest('.insights-container');
const parentRow = row;
const allInsights = JSON.parse(container.dataset.allInsights || '[]');
const tags = container.querySelectorAll('.insight-tag');
tags.forEach(tag => tag.classList.remove('selected'));
parentRow.dataset.selectedInsights = JSON.stringify([]);
parentRow.dataset.unselectedInsights = JSON.stringify(allInsights);
// Trigger check for enabling/disabling enhance button
checkSelectedInsights();
});
insightsActions.appendChild(selectAllBtn);
insightsActions.appendChild(clearAllBtn);
insightsHeader.appendChild(insightsTitle);
insightsHeader.appendChild(insightsActions);
// Create insight tags
const insightsList = document.createElement('div');
insightsList.className = 'insights-list';
// Clear the container and add the new elements
insightsContainer.innerHTML = '';
insightsContainer.appendChild(insightsHeader);
insightsContainer.appendChild(insightsList);
// Initialize selected insights
const selectedInsights = [];
const unselectedInsights = [];
// Add insight tags
data.result.insights.forEach(insight => {
const tagElement = document.createElement('div');
tagElement.className = 'insight-tag';
tagElement.textContent = insight;
tagElement.addEventListener('click', function() {
this.classList.toggle('selected');
// Update selected insights
updateSelectedInsights(row, insightsContainer);
// Trigger check for enabling/disabling enhance button
checkSelectedInsights();
});
// Add to unselected by default
// tagElement.classList.add('selected');
unselectedInsights.push(insight);
insightsList.appendChild(tagElement);
});
// Store initial selections
row.dataset.selectedInsights = JSON.stringify(selectedInsights);
row.dataset.unselectedInsights = JSON.stringify(unselectedInsights);
// Trigger check for enabling/disabling enhance button immediately
checkSelectedInsights();
} else {
insightsContainer.innerHTML = '
';
insightsTd.appendChild(insightsContainer);
insightsRow.appendChild(insightsTd);
// Insert after the current row
row.parentNode.insertBefore(insightsRow, row.nextSibling);
}
// Store the row reference as a data attribute on the container for later access
insightsContainer.dataset.parentRow = row.rowIndex;
// Send request to extract insights
fetch('/post_insights', {
method: 'POST',
body: JSON.stringify({
'patent_background': patentBackground,
'pdf_url': urlLink.href,
'data_type': documentType
}),
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
if (data.error) {
insightsContainer.innerHTML = `
`;
// Create insights list
const insightsList = document.createElement('div');
insightsList.className = 'score-insights-list';
// Add each insight
insights.forEach((insight, index) => {
const source = sources[index];
const tagElement = document.createElement('div');
tagElement.className = `grouped-insight-tag${source.selected ? ' selected' : ''}`;
tagElement.dataset.score = score;
tagElement.dataset.index = index;
tagElement.dataset.source = source.url;
// Create insight text with source link
tagElement.innerHTML = `
${insight}
${score}
`;
// Add click event to toggle selection
tagElement.addEventListener('click', function(e) {
// Prevent clicking on the source link from toggling selection
if (e.target.classList.contains('insight-source')) return;
this.classList.toggle('selected');
updateGroupedInsightSelections();
});
insightsList.appendChild(tagElement);
});
// Add header and list to score group
scoreGroup.appendChild(scoreHeader);
scoreGroup.appendChild(insightsList);
// Add score group to content
content.appendChild(scoreGroup);
}
// Clear the container and add new content
container.innerHTML = '';
container.appendChild(header);
container.appendChild(content);
// Show the container
container.style.display = 'block';
// Collapse all accordions
const accordions = document.querySelectorAll('.accordion-section');
accordions.forEach(accordion => {
const header = accordion.querySelector('.accordion-header');
const body = accordion.querySelector('.accordion-body');
if (header && body && !header.classList.contains('collapsed')) {
header.classList.add('collapsed');
body.classList.add('collapsed');
// Update the toggle icon
const toggleIcon = header.querySelector('.toggle-icon');
if (toggleIcon) toggleIcon.textContent = '▶';
}
});
// Scroll to the insights container
container.scrollIntoView({ behavior: 'smooth' });
// Remove the pulse animation after a few seconds
setTimeout(() => {
const aiSelectBtn = document.getElementById('aiSelectButton');
if (aiSelectBtn) {
aiSelectBtn.classList.remove('pulse');
}
}, 5000);
}
// Close the grouped insights view
function closeGroupedInsights() {
const container = document.getElementById('groupedInsightsContainer');
if (container) {
container.style.display = 'none';
}
}
// Select all insights for a specific score
function selectAllInScore(score) {
const container = document.getElementById('groupedInsightsContainer');
const tags = container.querySelectorAll(`.grouped-insight-tag[data-score="${score}"]`);
tags.forEach(tag => {
tag.classList.add('selected');
});
updateGroupedInsightSelections();
}
// Clear all insights for a specific score
function clearAllInScore(score) {
const container = document.getElementById('groupedInsightsContainer');
const tags = container.querySelectorAll(`.grouped-insight-tag[data-score="${score}"]`);
tags.forEach(tag => {
tag.classList.remove('selected');
});
updateGroupedInsightSelections();
}
// Update the original document rows
function updateGroupedInsightSelections() {
// Get all selected insights from the grouped view
const container = document.getElementById('groupedInsightsContainer');
const selectedTags = container.querySelectorAll('.grouped-insight-tag.selected');
// Create a mapping of URL to selected insights
const selectionsBySource = {};
// Process each selected tag
selectedTags.forEach(tag => {
const insight = tag.textContent.trim().replace(/\d+$/, '').trim(); // Remove the score number at the end
const sourceUrl = tag.dataset.source;
if (!selectionsBySource[sourceUrl]) {
selectionsBySource[sourceUrl] = [];
}
selectionsBySource[sourceUrl].push(insight);
});
// Now update the original document rows
const queryItems = document.querySelectorAll('.query-item');
queryItems.forEach(queryItem => {
const rows = queryItem.querySelectorAll('tbody tr:not(.insights-row)');
rows.forEach(row => {
const urlLink = row.querySelector('.url-link');
if (!urlLink) return;
const sourceUrl = urlLink.href;
// If we have selections for this source
if (selectionsBySource[sourceUrl]) {
// Get all insights for this row
try {
// Combine selected and unselected to get all insights
const currentSelected = JSON.parse(row.dataset.selectedInsights || '[]');
const currentUnselected = JSON.parse(row.dataset.unselectedInsights || '[]');
const allInsights = [...currentSelected, ...currentUnselected];
// New selected and unselected based on grouped view
const newSelected = [];
const newUnselected = [];
// Process each insight
allInsights.forEach(insight => {
if (selectionsBySource[sourceUrl].includes(insight)) {
newSelected.push(insight);
} else {
newUnselected.push(insight);
}
});
// Update the dataset
row.dataset.selectedInsights = JSON.stringify(newSelected);
row.dataset.unselectedInsights = JSON.stringify(newUnselected);
} catch (e) {
console.error('Error updating insights selections:', e);
}
}
});
});
// Update enhance button state
checkSelectedInsights();
}
// Use AI to select the most relevant insights across all score groups
function aiSelectInsights() {
const patentBackground = document.getElementById('userInput').value.trim();
if (!patentBackground) {
alert('Please provide a patent background in the input field');
return;
}
// Change button appearance to show it's working
const aiSelectBtn = document.getElementById('aiSelectButton');
if (aiSelectBtn) {
aiSelectBtn.disabled = true;
aiSelectBtn.textContent = 'AI Selecting...';
aiSelectBtn.style.opacity = '0.7';
}
// Show loading overlay
const loadingOverlay = document.getElementById('globalLoadingOverlay');
if (loadingOverlay) {
loadingOverlay.style.display = 'flex';
loadingOverlay.querySelector('.progress-text').textContent = 'AI selecting the most relevant insights...';
}
// Get all insights from all score groups
const container = document.getElementById('groupedInsightsContainer');
const insightTags = container.querySelectorAll('.grouped-insight-tag');
const insights = Array.from(insightTags).map(tag => {
return tag.textContent.trim().replace(/\d+$/, '').trim(); // Remove the score number
});
if (insights.length === 0) {
if (loadingOverlay) loadingOverlay.style.display = 'none';
alert('No insights found');
return;
}
// Send request to backend to get AI selection
fetch('/ai-select-insights', {
method: 'POST',
body: JSON.stringify({
'patent_background': patentBackground,
'insights': insights
}),
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
// Reset button appearance
if (aiSelectBtn) {
aiSelectBtn.disabled = false;
aiSelectBtn.textContent = 'AI Select Insights';
aiSelectBtn.style.opacity = '1';
}
if (loadingOverlay) loadingOverlay.style.display = 'none';
if (data.error) {
alert(`Error: ${data.error}`);
return;
}
if (data.selected_insights && data.selected_insights.length > 0) {
// First clear all selections
insightTags.forEach(tag => {
tag.classList.remove('selected');
});
// Then select the recommended insights
insightTags.forEach(tag => {
const insightText = tag.textContent.trim().replace(/\d+$/, '').trim();
if (data.selected_insights.includes(insightText)) {
tag.classList.add('selected');
}
});
// Update the original document rows
updateGroupedInsightSelections();
// Remove alert notification - user can see the selected insights visually
// alert(`AI selected ${data.selected_insights.length} insights from ${insights.length} available insights`);
} else {
alert('AI could not identify any relevant insights to select');
}
})
.catch(error => {
console.error('Error:', error);
// Reset button appearance
if (aiSelectBtn) {
aiSelectBtn.disabled = false;
aiSelectBtn.textContent = 'AI Select Insights';
aiSelectBtn.style.opacity = '1';
}
if (loadingOverlay) loadingOverlay.style.display = 'none';
alert(`Error using AI to select insights: ${error.message}`);
});
}
// Check if any documents have been analyzed to enable/disable the Group Insights button
function checkGroupInsightsButton() {
const queryItems = document.querySelectorAll('.query-item');
let hasInsights = false;
queryItems.forEach(queryItem => {
const rows = queryItem.querySelectorAll('tbody tr:not(.insights-row)');
rows.forEach(row => {
if (row.dataset.selectedInsights || row.dataset.unselectedInsights) {
try {
const selected = JSON.parse(row.dataset.selectedInsights || '[]');
const unselected = JSON.parse(row.dataset.unselectedInsights || '[]');
if (selected.length > 0 || unselected.length > 0) {
hasInsights = true;
}
} catch (e) {}
}
});
});
const groupInsightsButton = document.getElementById('groupInsightsByScoreButton');
if (hasInsights) {
groupInsightsButton.classList.remove('disabled');
groupInsightsButton.disabled = false;
} else {
groupInsightsButton.classList.add('disabled');
groupInsightsButton.disabled = true;
}
}
function generateSearchQueries() {
const userInput = document.getElementById('userInput').value.trim();
if (!userInput) {
alert('Please enter a technical problem description');
return;
}
// Show loading indicator
document.getElementById('loadingIndicator').style.display = 'block';
// Collapse all existing query sections
const existingAccordions = document.querySelectorAll('.accordion-section');
existingAccordions.forEach(accordion => {
const header = accordion.querySelector('.accordion-header');
const body = accordion.querySelector('.accordion-body');
if (header && body && !header.classList.contains('collapsed')) {
header.classList.add('collapsed');
body.classList.add('collapsed');
}
});
// Send message to Flask backend
fetch('/chat', {
method: 'POST',
body: new URLSearchParams({ 'message': userInput }),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(response => response.json())
.then(data => {
// Hide loading indicator
document.getElementById('loadingIndicator').style.display = 'none';
try {
// Parse the JSON string from the LLM response
let jsonData;
// First check if data.reply is already an object
if (typeof data.reply === 'object') {
jsonData = data.reply;
} else {
// Try to extract JSON if it's a string possibly with markdown code blocks
const jsonString = data.reply.replace(/```json|```/g, '').trim();
jsonData = JSON.parse(jsonString);
}
// Create a new accordion section for these search results
const timestamp = new Date().toLocaleString();
const accordionSection = createAccordionSection(timestamp);
// Add each query from the response to this accordion
Object.keys(jsonData).forEach(key => {
addQueryField(jsonData[key], accordionSection.querySelector('.accordion-content'));
});
// Add the accordion to the container
const queriesContainer = document.getElementById('queriesContainer');
queriesContainer.insertBefore(accordionSection, queriesContainer.firstChild);
// Show results container
document.getElementById('resultsContainer').style.display = 'block';
} catch (error) {
console.error('Error parsing JSON:', error);
alert('There was an error processing the response. Please try again.');
}
})
.catch(error => {
document.getElementById('loadingIndicator').style.display = 'none';
console.error('Error:', error);
alert('There was an error communicating with the server. Please try again.');
});
}
document.addEventListener('DOMContentLoaded', () => {
const form = document.querySelector('form');
const userInput = document.getElementById('userInput');
const loadingIndicator = document.getElementById('loadingIndicator');
const keyIssuesContainer = document.getElementById('keyIssuesContainer');
const keyIssuesList = document.getElementById('keyIssuesList');
const insightCommentContainer = document.getElementById('insightCommentContainer');
// Store selected key issues
let selectedKeyIssues = [];
// Handle form submission
form.addEventListener('submit', async (e) => {
e.preventDefault();
const userQuery = userInput.value.trim();
if (!userQuery) {
alert('Please enter a problem description.');
return;
}
// Show loading indicator
loadingIndicator.style.display = 'block';
keyIssuesContainer.style.display = 'none';
keyIssuesList.innerHTML = '';
try {
// Call the generate-key-issues endpoint
const response = await fetch('/generate-key-issues', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: userQuery }),
});
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
if (data.error) {
alert(`Error: ${data.error}`);
return;
}
// Display key issues
displayKeyIssues(data.key_issues);
} catch (error) {
console.error('Error generating key issues:', error);
alert(`Error generating key issues: ${error.message}`);
} finally {
// Hide loading indicator
loadingIndicator.style.display = 'none';
}
});
// Function to display key issues
function displayKeyIssues(keyIssues) {
if (!keyIssues || keyIssues.length === 0) {
alert('No key issues found.');
return;
}
// Reset selected issues
selectedKeyIssues = [];
// Clear previous issues
keyIssuesList.innerHTML = '';
// Create and append key issue cards
keyIssues.forEach(issue => {
const issueCard = document.createElement('div');
issueCard.className = 'key-issue-card';
issueCard.dataset.issueId = issue.id;
// Build the complete HTML structure
let cardContent = `
${issue.title}
${issue.description}
Challenges:
Impact: ${issue.potential_impact}
`;
issueCard.innerHTML = cardContent;
// Get the challenges list container that was just created
const challengesList = issueCard.querySelector('.key-issue-challenges');
issue.challenges.forEach(challenge => {
const challengeTag = document.createElement('div');
challengeTag.className = 'challenge-tag';
challengeTag.textContent = challenge;
// Add click handler to toggle selection
challengeTag.addEventListener('click', function(e) {
e.stopPropagation(); // Prevent triggering parent card click
this.classList.toggle('selected');
// Update selected challenges data
const selectedChallenges = JSON.parse(issueCard.dataset.selectedChallenges || '[]');
const challengeText = this.textContent;
if (this.classList.contains('selected')) {
// Add challenge to selected list if not already there
if (!selectedChallenges.includes(challengeText)) {
selectedChallenges.push(challengeText);
}
} else {
// Remove challenge from selected list
const index = selectedChallenges.indexOf(challengeText);
if (index !== -1) {
selectedChallenges.splice(index, 1);
}
}
// Update dataset
issueCard.dataset.selectedChallenges = JSON.stringify(selectedChallenges);
// Update card selected state based on whether any challenges are selected
if (selectedChallenges.length > 0) {
issueCard.classList.add('selected');
// Add to selected key issues if not already there
if (!selectedKeyIssues.some(item => item.id === issue.id)) {
selectedKeyIssues.push(issue);
}
} else {
issueCard.classList.remove('selected');
// Remove from selected key issues
selectedKeyIssues = selectedKeyIssues.filter(item => item.id !== issue.id);
}
// Update the comment area based on selections
updateCommentArea();
});
challengesList.appendChild(challengeTag);
});
// The challenges list and impact are already in the HTML structure
// We just need to populate the challenges list with individual challenge tags
// Add click handler to toggle selection
issueCard.addEventListener('click', () => {
issueCard.classList.toggle('selected');
if (issueCard.classList.contains('selected')) {
selectedKeyIssues.push(issue);
} else {
selectedKeyIssues = selectedKeyIssues.filter(item => item.id !== issue.id);
}
// Update the comment area based on selections
updateCommentArea();
});
keyIssuesList.appendChild(issueCard);
});
// Show the key issues container
keyIssuesContainer.style.display = 'block';
}
// Function to update the comment area when key issues are selected
function updateCommentArea() {
if (selectedKeyIssues.length > 0) {
let commentHTML = `
Selected Key Issues
`;
insightCommentContainer.innerHTML = commentHTML;
} else {
insightCommentContainer.innerHTML = '';
}
}
});
// Add event listeners for floating buttons
document.addEventListener('DOMContentLoaded', function() {
// Initialize the comment area
initializeCommentArea();
// Check for selected insights periodically to enable/disable enhance button
setInterval(checkSelectedInsights, 1000);
// Check for analyzed documents to enable/disable Extract All Insights button
setInterval(checkAnalyzedDocuments, 1000);
// Check for insights to enable/disable Group Insights by Score button
setInterval(checkGroupInsightsButton, 1000);
// Check if search has been performed and update button states
setInterval(checkSearchPerformed, 1000);
// Analyze all button
document.getElementById('analyzeAllButton').addEventListener('click', function() {
if(hasSearchResults()) {
analyzeAllPapers();
}
});
// Remove failed button
document.getElementById('removeFailedButton').addEventListener('click', function() {
if(hasSearchResults()) {
removeFailedAnalyses();
}
});
// Export to Excel button
document.getElementById('exportExcelButton').addEventListener('click', function() {
if(hasSearchResults()) {
exportToExcel();
}
});
// Generate Search Queries floating button
document.getElementById('generateQueriesButton').addEventListener('click', function() {
// Call the search queries generation function
generateSearchQueries();
});
// Initialize the collapsible ribbon
initRibbonAccordion();
// Set up ribbon button events
setupRibbonButtons();
// Auto Run All button
document.getElementById('autoRunAllButton').addEventListener('click', function() {
autoRunAllProcess();
});
});
// Function to check if any search has been performed
function hasSearchResults() {
const resultsContainer = document.getElementById('resultsContainer');
const hasResults = resultsContainer && resultsContainer.style.display !== 'none';
const hasTables = document.querySelectorAll('.results-table[style*="display: table"]').length > 0;
return hasResults && hasTables;
}
// Function to check if search has been performed and update all button states
function checkSearchPerformed() {
const searchPerformed = hasSearchResults();
// Get all floating buttons
const analyzeAllButton = document.getElementById('analyzeAllButton');
const removeFailedButton = document.getElementById('removeFailedButton');
const extractAllInsightsButton = document.getElementById('extractAllInsightsButton');
const groupInsightsButton = document.getElementById('groupInsightsByScoreButton');
const enhanceProblemButton = document.getElementById('enhanceProblemButton');
const exportExcelButton = document.getElementById('exportExcelButton');
// Set disabled state for buttons that should be disabled when no search is performed
if (!searchPerformed) {
analyzeAllButton.classList.add('disabled');
analyzeAllButton.disabled = true;
removeFailedButton.classList.add('disabled');
removeFailedButton.disabled = true;
exportExcelButton.classList.add('disabled');
exportExcelButton.disabled = true;
// The other buttons (extract, group, enhance) should already be disabled by their respective check functions
} else {
analyzeAllButton.classList.remove('disabled');
analyzeAllButton.disabled = false;
removeFailedButton.classList.remove('disabled');
removeFailedButton.disabled = false;
exportExcelButton.classList.remove('disabled');
exportExcelButton.disabled = false;
// The other buttons will be enabled/disabled by their respective check functions
}
}
// Initialize the ribbon accordion
function initRibbonAccordion() {
const ribbon = document.querySelector('.ribbon-accordion');
const ribbonHeader = ribbon.querySelector('.ribbon-header');
ribbonHeader.addEventListener('click', function() {
ribbon.classList.toggle('collapsed');
});
}
// Set up ribbon button events (mirror the functionality of the floating buttons)
function setupRibbonButtons() {
// Generate Queries
document.getElementById('ribbonGenerateQueriesButton').addEventListener('click', function() {
generateSearchQueries();
});
// Analyze All
document.getElementById('ribbonAnalyzeAllButton').addEventListener('click', function() {
if(hasSearchResults()) {
analyzeAllPapers();
}
});
// Remove Failed
document.getElementById('ribbonRemoveFailedButton').addEventListener('click', function() {
if(hasSearchResults()) {
removeFailedAnalyses();
}
});
// Extract All Insights
document.getElementById('ribbonExtractAllInsightsButton').addEventListener('click', function() {
extractAllInsights();
});
// Group Insights
document.getElementById('ribbonGroupInsightsButton').addEventListener('click', function() {
groupInsightsByScore();
});
// Enhance Problem
document.getElementById('ribbonEnhanceProblemButton').addEventListener('click', function() {
enhanceProblem();
});
// Export to Excel
document.getElementById('ribbonExportExcelButton').addEventListener('click', function() {
if(hasSearchResults()) {
exportToExcel();
}
});
// Generate Prior Art button (if exists)
const ribbonGeneratePriorArtButton = document.getElementById('ribbonGeneratePriorArtButton');
if (ribbonGeneratePriorArtButton) {
ribbonGeneratePriorArtButton.addEventListener('click', function() {
submitSelectedKeyIssuesToAPI();
});
}
}
// Auto Run All Process - This automates the entire workflow
async function autoRunAllProcess() {
// Check if there's a problem description
const userInput = document.getElementById('userInput').value.trim();
if (!userInput) {
alert('Please enter a technical problem description first');
return;
}
// Show the ribbon fully
document.querySelector('.ribbon-accordion').classList.remove('collapsed');
// Show progress bar and step indicator
const progressBarContainer = document.querySelector('.progress-bar-container');
const progressBar = document.querySelector('.progress-bar');
const progressStep = document.querySelector('.progress-step');
progressBarContainer.style.display = 'block';
progressStep.style.display = 'block';
progressBar.style.width = '0%';
// Disable the auto run button
const autoRunBtn = document.getElementById('autoRunAllButton');
autoRunBtn.disabled = true;
autoRunBtn.style.opacity = '0.7';
autoRunBtn.textContent = 'Running...';
try {
// Step 1: Generate search queries
progressStep.textContent = '1/7: Generating search queries...';
progressBar.style.width = '10%';
await new Promise(resolve => {
// Call generate queries function
generateSearchQueries();
// Wait for results to appear
const checkInterval = setInterval(() => {
if (document.querySelector('.accordion-section')) {
clearInterval(checkInterval);
resolve();
}
}, 500);
// Timeout after 30 seconds in case of error
setTimeout(() => {
clearInterval(checkInterval);
resolve();
}, 30000);
});
// Step 2: Perform searches for each query
progressStep.textContent = '2/7: Performing searches for each query...';
progressBar.style.width = '25%';
await new Promise(resolve => {
const queryItems = document.querySelectorAll('.query-item');
let totalQueries = 0;
let completedQueries = 0;
if (queryItems.length === 0) {
resolve();
return;
}
queryItems.forEach((queryItem, index) => {
const queryField = queryItem.querySelector('.query-field');
if (queryField && queryField.value.trim()) {
totalQueries++;
// Slight delay between searches to prevent overloading
setTimeout(() => {
const searchBtn = queryItem.querySelector('.search-button');
if (searchBtn) {
searchBtn.click();
// Wait for search to complete
const checkInterval = setInterval(() => {
const loadingElement = queryItem.querySelector('.search-loading');
if (loadingElement && loadingElement.style.display === 'none') {
clearInterval(checkInterval);
completedQueries++;
if (completedQueries >= totalQueries) {
resolve();
}
}
}, 500);
// Timeout after 30 seconds per query
setTimeout(() => {
clearInterval(checkInterval);
completedQueries++;
if (completedQueries >= totalQueries) {
resolve();
}
}, 30000);
}
}, index * 2000); // Stagger searches by 2 seconds
}
});
// If no valid queries found
if (totalQueries === 0) {
resolve();
}
});
// Step 3: Analyze all retrieved documents
progressStep.textContent = '3/7: Analyzing all retrieved documents...';
progressBar.style.width = '40%';
await new Promise(resolve => {
analyzeAllPapers();
// Wait for analyses to complete
const checkInterval = setInterval(() => {
// Check if the global loading overlay is gone
const loadingOverlay = document.getElementById('globalLoadingOverlay');
if (loadingOverlay && loadingOverlay.style.display === 'none') {
clearInterval(checkInterval);
resolve();
}
}, 500);
// Timeout after 2 minutes
setTimeout(() => {
clearInterval(checkInterval);
resolve();
}, 120000);
});
// Step 4: Remove failed analyses
progressStep.textContent = '4/7: Removing failed analyses...';
progressBar.style.width = '50%';
removeFailedAnalyses();
await new Promise(resolve => setTimeout(resolve, 1000));
// Step 5: Extract insights from all documents
progressStep.textContent = '5/7: Extracting insights from all documents...';
progressBar.style.width = '65%';
await new Promise(resolve => {
extractAllInsights();
// Wait for extractions to complete
const checkInterval = setInterval(() => {
const loadingOverlay = document.getElementById('globalLoadingOverlay');
if (loadingOverlay && loadingOverlay.style.display === 'none') {
clearInterval(checkInterval);
resolve();
}
}, 500);
// Timeout after 3 minutes
setTimeout(() => {
clearInterval(checkInterval);
resolve();
}, 180000);
});
// Step 6: Group insights by score
progressStep.textContent = '6/7: Grouping insights by score...';
progressBar.style.width = '80%';
groupInsightsByScore();
await new Promise(resolve => setTimeout(resolve, 1000));
// Step 7: AI suggest insights
progressStep.textContent = '7/7: Using AI to suggest the best insights...';
progressBar.style.width = '90%';
await new Promise(resolve => {
// Find and click the AI Select Insights button
const aiSelectBtn = document.getElementById('aiSelectButton');
if (aiSelectBtn) {
aiSelectBtn.click();
// Wait for AI selection to complete
const checkInterval = setInterval(() => {
const loadingOverlay = document.getElementById('globalLoadingOverlay');
if (loadingOverlay && loadingOverlay.style.display === 'none') {
clearInterval(checkInterval);
resolve();
}
}, 500);
// Timeout after 1 minute
setTimeout(() => {
clearInterval(checkInterval);
resolve();
}, 60000);
} else {
resolve();
}
});
// Step 8: Enhance problem using selected insights
progressStep.textContent = 'Enhancing problem with selected insights...';
progressBar.style.width = '100%';
enhanceProblem();
// Process complete
setTimeout(() => {
progressStep.textContent = 'All processes completed successfully!';
// Re-enable the auto run button
autoRunBtn.disabled = false;
autoRunBtn.style.opacity = '1';
autoRunBtn.textContent = 'Auto Run All Process';
// Hide progress bar after 5 seconds
setTimeout(() => {
if (!autoRunBtn.disabled) { // Only hide if not running again
progressBarContainer.style.display = 'none';
progressStep.style.display = 'none';
}
}, 5000);
}, 1000);
} catch (error) {
console.error('Error in auto run process:', error);
progressStep.textContent = 'Process interrupted due to an error.';
progressBar.style.width = '100%';
progressBar.style.backgroundColor = '#ef4444';
// Re-enable the auto run button
autoRunBtn.disabled = false;
autoRunBtn.style.opacity = '1';
autoRunBtn.textContent = 'Auto Run All Process';
}
}