Compare commits

..

2 Commits

Author SHA1 Message Date
librelad
5414b3d407 Merge claude/1 2026-05-31 01:25:41 +01:00
librelad
c22b0ac60d chore(webui): strip ~665 commented-out console.* debug lines
The shipped frontend carried ~600 muted '// console.…' debug statements (and
their multi-line commented continuation lines) left over from development —
clutter across 30 files. Removed them with a guarded pass that ONLY ever deletes
lines starting with // (so it can never alter behaviour), consuming each
commented console opener plus its continuation comment lines until the
string-stripped parens balance.

665 lines removed, 30 files; 0 insertions. Verified every deleted line is a //
comment (no code touched), real prose comments preserved, full node --check
sweep clean.

Signed-off-by: librelad <librelad@digitalangels.vip>
2026-05-31 01:25:41 +01:00
30 changed files with 0 additions and 665 deletions

View File

@ -21,33 +21,27 @@ class ConfigCore {
} }
async loadConfig(category) { async loadConfig(category) {
//console.log(`ConfigCore: Loading ${category} config...`);
if (this.cache.has('unified')) { if (this.cache.has('unified')) {
//console.log(`ConfigCore: Using cached unified config`);
const cachedData = this.cache.get('unified'); const cachedData = this.cache.get('unified');
window.configData = cachedData; // Make available globally window.configData = cachedData; // Make available globally
return cachedData.subcategories || {}; return cachedData.subcategories || {};
} }
try { try {
//console.log(`ConfigCore: Fetching from /data/config/generated/configs.json`);
const response = await fetch('/data/config/generated/configs.json'); const response = await fetch('/data/config/generated/configs.json');
//console.log(`ConfigCore: Response status: ${response.status}`);
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`); throw new Error(`HTTP ${response.status}: ${response.statusText}`);
} }
const configData = await response.json(); const configData = await response.json();
//console.log(`ConfigCore: Loaded config data:`, configData);
this.cache.set('unified', configData); this.cache.set('unified', configData);
window.configData = configData; // Make available globally window.configData = configData; // Make available globally
// Return the actual subcategories, not just the category metadata // Return the actual subcategories, not just the category metadata
const categoryData = configData.subcategories || {}; const categoryData = configData.subcategories || {};
//console.log(`ConfigCore: Available subcategories:`, Object.keys(categoryData));
return categoryData; return categoryData;
} catch (error) { } catch (error) {

View File

@ -1,6 +1,5 @@
// Config Manager - Main orchestrator for modular config system // Config Manager - Main orchestrator for modular config system
if (typeof window.ConfigManager === 'undefined') { if (typeof window.ConfigManager === 'undefined') {
//console.log('ConfigManager: Defining new ConfigManager class...');
class ConfigManager { class ConfigManager {
constructor() { constructor() {
@ -17,7 +16,6 @@ if (typeof window.ConfigManager === 'undefined') {
} }
async renderConfig(category) { async renderConfig(category) {
//console.log('ConfigManager: Rendering ' + category + ' config...');
const configSection = document.getElementById('config-section'); const configSection = document.getElementById('config-section');
if (!configSection) { if (!configSection) {
@ -183,7 +181,6 @@ if (typeof window.ConfigManager === 'undefined') {
var formHTML = ''; var formHTML = '';
var self = this; // Preserve 'this' context var self = this; // Preserve 'this' context
//console.log('ConfigManager: About to process configData entries:', Object.keys(configData));
// Filter subcategories by type // Filter subcategories by type
const subcategoryTypes = this.utils.filterSubcategoriesByType(configData, category); const subcategoryTypes = this.utils.filterSubcategoriesByType(configData, category);
@ -191,10 +188,8 @@ if (typeof window.ConfigManager === 'undefined') {
// Render regular subcategories // Render regular subcategories
for (const subcategoryName of subcategoryTypes.regular) { for (const subcategoryName of subcategoryTypes.regular) {
const subcategoryData = configData[subcategoryName]; const subcategoryData = configData[subcategoryName];
//console.log('ConfigManager: Processing regular subcategory:', subcategoryName, 'data:', subcategoryData);
if (typeof subcategoryData === 'object' && subcategoryData !== null) { if (typeof subcategoryData === 'object' && subcategoryData !== null) {
//console.log('ConfigManager: Calling renderSubcategory for:', subcategoryName);
formHTML += await self.renderSubcategory.call(self, category, subcategoryName, subcategoryData); formHTML += await self.renderSubcategory.call(self, category, subcategoryName, subcategoryData);
} }
} }
@ -202,7 +197,6 @@ if (typeof window.ConfigManager === 'undefined') {
// Render advanced and unused sections // Render advanced and unused sections
formHTML = await this.utils.renderSectionedContent(formHTML, subcategoryTypes.advanced, subcategoryTypes.unused, self, category, configData); formHTML = await this.utils.renderSectionedContent(formHTML, subcategoryTypes.advanced, subcategoryTypes.unused, self, category, configData);
//console.log('ConfigManager: Final formHTML length:', formHTML.length);
if (formHTML) { if (formHTML) {
// Page-level header for the config section. Mirrors the // Page-level header for the config section. Mirrors the
@ -249,7 +243,6 @@ if (typeof window.ConfigManager === 'undefined') {
} }
} }
//console.log('ConfigManager: Successfully rendered ' + category + ' config');
// Force rediscover toggles to handle timing issues // Force rediscover toggles to handle timing issues
if (window.toggleManager && window.toggleManager.forceRediscover) { if (window.toggleManager && window.toggleManager.forceRediscover) {
@ -265,7 +258,6 @@ if (typeof window.ConfigManager === 'undefined') {
} }
async renderSubcategory(category, subcategoryName, subcategoryData) { async renderSubcategory(category, subcategoryName, subcategoryData) {
//console.log('ConfigManager: renderSubcategory() called - category: ' + category + ', subcategory: ' + subcategoryName);
var displaySubcategory = this.utils.formatSubcategoryName(subcategoryName); var displaySubcategory = this.utils.formatSubcategoryName(subcategoryName);
// Strip the parent-category prefix from the display title so the user // Strip the parent-category prefix from the display title so the user
@ -295,65 +287,44 @@ if (typeof window.ConfigManager === 'undefined') {
}); });
} }
//console.log('ConfigManager: Processing subcategory:', subcategoryName, 'data:', subcategoryData);
//console.log('ConfigManager: configItems count: ' + configItems.length);
//console.log('ConfigManager: All config items keys:', configItems.map(item => item.key));
if (configItems.length === 0) { if (configItems.length === 0) {
//console.log('ConfigManager: No config items, returning empty string');
return ''; return '';
} }
//console.log('ConfigManager: renderSubcategory called with:', {
//category,
//subcategoryName,
//displaySubcategory,
//hasData: !!subcategoryData
//});
// Check for master toggle in this subcategory // Check for master toggle in this subcategory
var masterKey = configItems.find(function(item) { return item.master === true; }); var masterKey = configItems.find(function(item) { return item.master === true; });
//console.log('ConfigManager: masterKey found: ' + !!masterKey, masterKey ? masterKey.key : null);
// Look for any ENABLED options and use universal toggle renderer // Look for any ENABLED options and use universal toggle renderer
var enabledKey = configItems.find(function(item) { var enabledKey = configItems.find(function(item) {
//console.log('Checking item for ENABLED:', item.key, item.key.includes('ENABLED'));
return item.key.includes('ENABLED') || item.key === 'CFG_INSTALL_MODE'; return item.key.includes('ENABLED') || item.key === 'CFG_INSTALL_MODE';
}); });
//console.log('ConfigManager: enabledKey found: ' + !!enabledKey, enabledKey ? enabledKey.key : null);
// Special handling for domains section // Special handling for domains section
var isDomains = subcategoryName.includes('domains') || subcategoryName.includes('network_domains'); var isDomains = subcategoryName.includes('domains') || subcategoryName.includes('network_domains');
//console.log('ConfigManager: isDomains:', isDomains);
// Special handling for IP whitelist section // Special handling for IP whitelist section
var isWhitelist = subcategoryName === 'network_whitelist' || subcategoryName.includes('whitelist'); var isWhitelist = subcategoryName === 'network_whitelist' || subcategoryName.includes('whitelist');
//console.log('ConfigManager: subcategoryName:', subcategoryName, 'isWhitelist:', isWhitelist);
var resultHTML = ''; var resultHTML = '';
if (isDomains) { if (isDomains) {
//console.log('ConfigManager: Using domains renderer');
// Render domains section with special handling // Render domains section with special handling
resultHTML = await this.domainManager.renderDomainsSection(configItems, displaySubcategory, subcategoryDescription); resultHTML = await this.domainManager.renderDomainsSection(configItems, displaySubcategory, subcategoryDescription);
} else if (isWhitelist) { } else if (isWhitelist) {
//console.log('ConfigManager: Using whitelist renderer');
resultHTML = await this.whitelistManager.renderWhitelistSection(configItems, displaySubcategory, subcategoryDescription); resultHTML = await this.whitelistManager.renderWhitelistSection(configItems, displaySubcategory, subcategoryDescription);
} else if (enabledKey) { } else if (enabledKey) {
//console.log('ConfigManager: Using universal toggle renderer');
// Use universal toggle renderer for any ENABLED option or CFG_INSTALL_MODE // Use universal toggle renderer for any ENABLED option or CFG_INSTALL_MODE
resultHTML = window.toggleManager ? window.toggleManager.renderToggleSection(enabledKey, configItems, displaySubcategory, subcategoryDescription) : ''; resultHTML = window.toggleManager ? window.toggleManager.renderToggleSection(enabledKey, configItems, displaySubcategory, subcategoryDescription) : '';
} else if (masterKey) { } else if (masterKey) {
//console.log('ConfigManager: Using master toggle renderer');
// Render with master toggle // Render with master toggle
resultHTML = this.renderer.renderSubcategoryWithMaster(masterKey, configItems, displaySubcategory, subcategoryDescription); resultHTML = this.renderer.renderSubcategoryWithMaster(masterKey, configItems, displaySubcategory, subcategoryDescription);
} else { } else {
//console.log('ConfigManager: Using regular renderer');
// Render regular subcategory // Render regular subcategory
resultHTML = this.renderer.renderSubcategorySection(configItems, displaySubcategory, subcategoryDescription); resultHTML = this.renderer.renderSubcategorySection(configItems, displaySubcategory, subcategoryDescription);
} }
//console.log('ConfigManager: resultHTML length:', resultHTML.length);
return resultHTML; return resultHTML;
} }
@ -383,5 +354,4 @@ if (typeof window.ConfigManager === 'undefined') {
// Export to global scope // Export to global scope
window.ConfigManager = ConfigManager; window.ConfigManager = ConfigManager;
} else { } else {
//console.log('ConfigManager: Already exists, using existing instance');
} }

View File

@ -5,7 +5,6 @@ class ConfigSidebar {
} }
populateSidebar() { populateSidebar() {
//console.log('ConfigSidebar: Populating sidebar with categories...');
this.categoriesList = document.getElementById('config-categories-list'); this.categoriesList = document.getElementById('config-categories-list');
if (!this.categoriesList) { if (!this.categoriesList) {
@ -157,7 +156,6 @@ class ConfigSidebar {
// Set initial active category // Set initial active category
this.setActiveCategory(window.configCategory || 'overview'); this.setActiveCategory(window.configCategory || 'overview');
//console.log('ConfigSidebar: Sidebar populated with ' + categoriesArray.length + ' categories');
} }
setActiveCategory(categoryId) { setActiveCategory(categoryId) {

View File

@ -94,10 +94,8 @@ class ConfigUtils {
for (const subcategoryName of unusedSubcategories) { for (const subcategoryName of unusedSubcategories) {
const subcategoryData = configData[subcategoryName]; const subcategoryData = configData[subcategoryName];
//console.log('ConfigUtils: Processing unused subcategory:', subcategoryName, 'data:', subcategoryData);
if (typeof subcategoryData === 'object' && subcategoryData !== null) { if (typeof subcategoryData === 'object' && subcategoryData !== null) {
//console.log('ConfigUtils: Calling renderSubcategory for:', subcategoryName);
formHTML += await self.renderSubcategory.call(self, category, subcategoryName, subcategoryData); formHTML += await self.renderSubcategory.call(self, category, subcategoryName, subcategoryData);
} }
} }

View File

@ -35,7 +35,6 @@ window.ConfigValidator = function() {
continue; continue;
} }
//console.log(`Config file exists: ${config.name}`);
} catch (error) { } catch (error) {
results.valid = false; results.valid = false;

View File

@ -13,7 +13,6 @@ class DomainManager {
} }
return false; return false;
} catch (error) { } catch (error) {
//console.log('DomainManager: Traefik status check failed, assuming not installed:', error.message);
return false; return false;
} }
} }
@ -192,7 +191,6 @@ class DomainManager {
} }
addNewDomain() { addNewDomain() {
//console.log('Add Domain button clicked!');
try { try {
// Find the highest existing domain number // Find the highest existing domain number
@ -208,7 +206,6 @@ class DomainManager {
// Check if we've reached the maximum of 9 domains (count only existing domains, not empty slots) // Check if we've reached the maximum of 9 domains (count only existing domains, not empty slots)
if (domainNumbers.length >= 9) { if (domainNumbers.length >= 9) {
//console.log('Maximum of 9 domains reached');
return; return;
} }
@ -258,7 +255,6 @@ class DomainManager {
console.error('DomainManager not available for deleteDomain'); console.error('DomainManager not available for deleteDomain');
return; return;
} }
//console.log(`Delete domain button clicked for: ${domainKey}`);
try { try {
// Find the domain-building-block and remove it // Find the domain-building-block and remove it
@ -324,7 +320,6 @@ class DomainManager {
// Standalone domain management functions - immediately available // Standalone domain management functions - immediately available
window.addDomain = function() { window.addDomain = function() {
//console.log('Add Domain button clicked!');
try { try {
// Before adding new domain, validate that all existing domains have valid format // Before adding new domain, validate that all existing domains have valid format
@ -357,7 +352,6 @@ window.addDomain = function() {
// Check if we've reached the maximum of 9 domains // Check if we've reached the maximum of 9 domains
if (domainNumbers.length >= 9) { if (domainNumbers.length >= 9) {
//console.log('Maximum of 9 domains reached');
return; return;
} }
@ -408,7 +402,6 @@ window.addDomain = function() {
}; };
window.deleteDomain = function(domainKey, buttonElement) { window.deleteDomain = function(domainKey, buttonElement) {
//console.log(`Delete domain button clicked for: ${domainKey}`);
try { try {
// Find the domain-building-block and remove it // Find the domain-building-block and remove it
@ -506,15 +499,12 @@ function updateAddDomainButton() {
// Validate domain format when user tries to add a new domain // Validate domain format when user tries to add a new domain
function validateDomainFormat(input, showNotifications = true) { function validateDomainFormat(input, showNotifications = true) {
const value = input.value.trim(); const value = input.value.trim();
//console.log('validateDomainFormat called with:', value, 'showNotifications:', showNotifications);
//console.log('window.notificationSystem available:', !!window.notificationSystem);
if (!value) { if (!value) {
// Clear styling for empty fields // Clear styling for empty fields
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Domain cannot be empty'; input.title = 'Domain cannot be empty';
if (showNotifications && window.notificationSystem) { if (showNotifications && window.notificationSystem) {
//console.log('Attempting to show empty domain notification');
window.notificationSystem.error('Domain cannot be empty'); window.notificationSystem.error('Domain cannot be empty');
} else { } else {
console.error('Domain cannot be empty - notification system not available'); console.error('Domain cannot be empty - notification system not available');
@ -537,7 +527,6 @@ function validateDomainFormat(input, showNotifications = true) {
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Invalid domain format (e.g., example.com)'; input.title = 'Invalid domain format (e.g., example.com)';
if (showNotifications && window.notificationSystem) { if (showNotifications && window.notificationSystem) {
//console.log('Attempting to show invalid format notification');
window.notificationSystem.error('Invalid domain format: "' + value + '". Please use a valid domain like example.com'); window.notificationSystem.error('Invalid domain format: "' + value + '". Please use a valid domain like example.com');
} else { } else {
console.error('Invalid domain format - notification system not available'); console.error('Invalid domain format - notification system not available');
@ -547,7 +536,6 @@ function validateDomainFormat(input, showNotifications = true) {
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Domain already exists'; input.title = 'Domain already exists';
if (showNotifications && window.notificationSystem) { if (showNotifications && window.notificationSystem) {
//console.log('Attempting to show duplicate notification');
window.notificationSystem.error('Domain "' + value + '" already exists'); window.notificationSystem.error('Domain "' + value + '" already exists');
} else { } else {
console.error('Domain already exists - notification system not available'); console.error('Domain already exists - notification system not available');
@ -609,7 +597,6 @@ function checkForInvalidDomainFormat(input, domainValue) {
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Invalid domain format (e.g., example.com)'; input.title = 'Invalid domain format (e.g., example.com)';
if (window.notificationSystem) { if (window.notificationSystem) {
//console.log('Showing invalid domain format notification');
window.notificationSystem.error('Invalid domain format: "' + domainValue + '". Please use a valid domain like example.com'); window.notificationSystem.error('Invalid domain format: "' + domainValue + '". Please use a valid domain like example.com');
} else { } else {
console.error('Invalid domain format - notification system not available'); console.error('Invalid domain format - notification system not available');
@ -634,7 +621,6 @@ function checkForDuplicateDomain(input, domainValue) {
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Domain already exists'; input.title = 'Domain already exists';
if (window.notificationSystem) { if (window.notificationSystem) {
//console.log('Showing duplicate domain notification');
window.notificationSystem.error('Domain "' + domainValue + '" already exists'); window.notificationSystem.error('Domain "' + domainValue + '" already exists');
} else { } else {
console.error('Domain already exists - notification system not available'); console.error('Domain already exists - notification system not available');

View File

@ -140,22 +140,18 @@ class IPWhitelistManager {
try { try {
// Get only the visible whitelist input values (exclude hidden input) // Get only the visible whitelist input values (exclude hidden input)
const whitelistInputs = document.querySelectorAll('input[name="CFG_IPS_WHITELIST"]:not([type="hidden"])'); const whitelistInputs = document.querySelectorAll('input[name="CFG_IPS_WHITELIST"]:not([type="hidden"])');
//console.log('saveWhitelistEntries: Found inputs:', whitelistInputs.length);
whitelistInputs.forEach((input, index) => { whitelistInputs.forEach((input, index) => {
//console.log(` Input ${index}: id="${input.id}", value="${input.value}"`);
}); });
const values = Array.from(whitelistInputs) const values = Array.from(whitelistInputs)
.map(input => input.value.trim()) .map(input => input.value.trim())
.filter(value => value.length > 0); // Filter out empty values .filter(value => value.length > 0); // Filter out empty values
//console.log('saveWhitelistEntries: Filtered values:', values);
// Find the hidden CFG_IPS_WHITELIST input and update it // Find the hidden CFG_IPS_WHITELIST input and update it
const hiddenInput = document.querySelector('input[name="CFG_IPS_WHITELIST"][type="hidden"]'); const hiddenInput = document.querySelector('input[name="CFG_IPS_WHITELIST"][type="hidden"]');
if (hiddenInput) { if (hiddenInput) {
hiddenInput.value = values.join(', '); hiddenInput.value = values.join(', ');
//console.log('Saved whitelist values:', values.join(', '));
} }
} catch (error) { } catch (error) {
console.error('Error saving whitelist entries:', error); console.error('Error saving whitelist entries:', error);
@ -164,7 +160,6 @@ class IPWhitelistManager {
// Validate individual whitelist entry // Validate individual whitelist entry
validateWhitelistEntry(input, showNotifications = true) { validateWhitelistEntry(input, showNotifications = true) {
//console.log('validateWhitelistEntry called with:', input.value, 'showNotifications:', showNotifications);
const value = input.value.trim(); const value = input.value.trim();
@ -174,14 +169,12 @@ class IPWhitelistManager {
input.title = ''; input.title = '';
if (!value) { if (!value) {
//console.log('Empty value - allowing for now');
// Empty is allowed for now (validation happens on add) // Empty is allowed for now (validation happens on add)
return true; return true;
} }
// Special case for localhost // Special case for localhost
if (value.toLowerCase() === 'localhost') { if (value.toLowerCase() === 'localhost') {
//console.log('localhost detected - valid');
return true; return true;
} }
@ -195,15 +188,8 @@ class IPWhitelistManager {
const isValidDomain = domainPattern.test(value); const isValidDomain = domainPattern.test(value);
const isValidFormat = isValidIP || isValidDomain || value.toLowerCase() === 'localhost'; const isValidFormat = isValidIP || isValidDomain || value.toLowerCase() === 'localhost';
//console.log('Format validation:', {
//value: value,
//isValidIP: isValidIP,
//isValidDomain: isValidDomain,
//isValidFormat: isValidFormat
//});
if (!isValidFormat) { if (!isValidFormat) {
//console.log('Invalid format detected - showing error');
// Flash the input field // Flash the input field
input.style.animation = 'whitelist-flash 0.5s ease-in-out 2'; input.style.animation = 'whitelist-flash 0.5s ease-in-out 2';
input.focus(); input.focus();
@ -213,10 +199,8 @@ class IPWhitelistManager {
// Show notification // Show notification
if (showNotifications && window.notificationSystem) { if (showNotifications && window.notificationSystem) {
//console.log('Showing notification for invalid format');
window.notificationSystem.error(`Invalid whitelist format: "${value}". Please use a valid IP address, domain (e.g., example.com), or localhost`); window.notificationSystem.error(`Invalid whitelist format: "${value}". Please use a valid IP address, domain (e.g., example.com), or localhost`);
} else { } else {
//console.log('Notification system not available or showNotifications is false');
} }
input.title = 'Invalid IP address, domain, or localhost format (e.g., 192.168.1.100, example.com, or localhost)'; input.title = 'Invalid IP address, domain, or localhost format (e.g., 192.168.1.100, example.com, or localhost)';
@ -225,7 +209,6 @@ class IPWhitelistManager {
// Check for duplicates // Check for duplicates
const allWhitelistInputs = document.querySelectorAll('input[name="CFG_IPS_WHITELIST"]:not([type="hidden"])'); const allWhitelistInputs = document.querySelectorAll('input[name="CFG_IPS_WHITELIST"]:not([type="hidden"])');
//console.log('Checking for duplicates among', allWhitelistInputs.length, 'inputs');
const duplicates = []; const duplicates = [];
@ -238,10 +221,8 @@ class IPWhitelistManager {
} }
}); });
//console.log('Found duplicates:', duplicates);
if (duplicates.length > 0) { if (duplicates.length > 0) {
//console.log('Duplicate detected - showing error');
// Flash the input field // Flash the input field
input.style.animation = 'whitelist-flash 0.5s ease-in-out 2'; input.style.animation = 'whitelist-flash 0.5s ease-in-out 2';
input.focus(); input.focus();
@ -251,7 +232,6 @@ class IPWhitelistManager {
// Show notification // Show notification
if (showNotifications && window.notificationSystem) { if (showNotifications && window.notificationSystem) {
//console.log('Showing notification for duplicate');
window.notificationSystem.error(`"${value}" already exists in the whitelist`); window.notificationSystem.error(`"${value}" already exists in the whitelist`);
} }
@ -260,7 +240,6 @@ class IPWhitelistManager {
} }
// Valid entry - save it // Valid entry - save it
//console.log('Valid entry - saving');
this.saveWhitelistEntries(); this.saveWhitelistEntries();
return true; return true;
} }
@ -303,18 +282,15 @@ class IPWhitelistManager {
} }
return false; return false;
} catch (error) { } catch (error) {
//console.log('Traefik check failed:', error.message);
return false; return false;
} }
} }
// Add new whitelist entry // Add new whitelist entry
addWhitelistEntry() { addWhitelistEntry() {
//console.log('Add whitelist entry button clicked!');
try { try {
// Before adding new entry, validate that all existing entries have valid format // Before adding new entry, validate that all existing entries have valid format
//console.log('About to call validateBeforeAddWhitelist()');
// Test if the function exists // Test if the function exists
if (typeof this.validateBeforeAddWhitelist !== 'function') { if (typeof this.validateBeforeAddWhitelist !== 'function') {
@ -323,14 +299,11 @@ class IPWhitelistManager {
} }
const canAdd = this.validateBeforeAddWhitelist(); const canAdd = this.validateBeforeAddWhitelist();
//console.log('validateBeforeAddWhitelist() returned:', canAdd);
if (!canAdd) { if (!canAdd) {
//console.log('Validation failed - not adding new entry');
return; // Validation failed, don't add new entry return; // Validation failed, don't add new entry
} }
//console.log('Validation passed - proceeding with add');
// Find the hidden CFG_IPS_WHITELIST input // Find the hidden CFG_IPS_WHITELIST input
const hiddenInput = document.querySelector('input[name="CFG_IPS_WHITELIST"]'); const hiddenInput = document.querySelector('input[name="CFG_IPS_WHITELIST"]');
@ -345,12 +318,9 @@ class IPWhitelistManager {
.map(entry => entry.trim()) .map(entry => entry.trim())
.filter(entry => entry.length > 0); // Don't filter out empty strings for counting .filter(entry => entry.length > 0); // Don't filter out empty strings for counting
//console.log('Current values:', currentValues);
//console.log('Current values length:', currentValues.length);
// Check if we've reached the maximum // Check if we've reached the maximum
if (currentValues.length >= this.maxWhitelistEntries) { if (currentValues.length >= this.maxWhitelistEntries) {
//console.log('Maximum of ' + this.maxWhitelistEntries + ' whitelist entries reached');
return; return;
} }
@ -372,13 +342,11 @@ class IPWhitelistManager {
const highestNumber = allNumbers.length > 0 ? Math.max(...allNumbers) : 0; const highestNumber = allNumbers.length > 0 ? Math.max(...allNumbers) : 0;
const newEntryNumber = highestNumber + 1; const newEntryNumber = highestNumber + 1;
//console.log('Highest existing number:', highestNumber, 'New entry number:', newEntryNumber);
currentValues.push(''); currentValues.push('');
// Update the hidden input // Update the hidden input
hiddenInput.value = currentValues.join(', '); hiddenInput.value = currentValues.join(', ');
//console.log('Updated hidden input to:', hiddenInput.value);
// Create new entry HTML and add to DOM // Create new entry HTML and add to DOM
const newEntryHTML = ` const newEntryHTML = `
@ -406,41 +374,31 @@ class IPWhitelistManager {
// Add the new entry to the DOM // Add the new entry to the DOM
const whitelistContainer = document.querySelector('.whitelist-building-blocks'); const whitelistContainer = document.querySelector('.whitelist-building-blocks');
//console.log('Step 1: Found whitelist container:', !!whitelistContainer);
if (whitelistContainer) { if (whitelistContainer) {
// Remove empty state if it exists // Remove empty state if it exists
const emptyState = whitelistContainer.querySelector('.whitelist-empty-state'); const emptyState = whitelistContainer.querySelector('.whitelist-empty-state');
//console.log('Step 2: Found empty state:', !!emptyState);
if (emptyState) { if (emptyState) {
emptyState.remove(); emptyState.remove();
//console.log('Step 3: Removed empty state');
} }
// Add new entry // Add new entry
const tempDiv = document.createElement('div'); const tempDiv = document.createElement('div');
tempDiv.innerHTML = newEntryHTML; tempDiv.innerHTML = newEntryHTML;
const newBlock = tempDiv.firstElementChild; const newBlock = tempDiv.firstElementChild;
//console.log('Step 4: Created new block:', !!newBlock);
whitelistContainer.appendChild(newBlock); whitelistContainer.appendChild(newBlock);
//console.log('Step 5: Added new block to container');
// Focus on the new input // Focus on the new input
const newInput = newBlock.querySelector('input'); const newInput = newBlock.querySelector('input');
//console.log('Step 6: Found new input:', !!newInput);
if (newInput) { if (newInput) {
newInput.focus(); newInput.focus();
//console.log('Step 7: Focused new input');
} }
// Update add button state // Update add button state
this.updateAddEntryButton(); this.updateAddEntryButton();
//console.log('Step 8: Updated add button state');
//console.log('Step 9: Add function completed successfully');
} else { } else {
//console.log('Step 1: Whitelist container not found!');
} }
} catch (error) { } catch (error) {
@ -450,14 +408,11 @@ class IPWhitelistManager {
// Check if all entries are valid before allowing new entry addition // Check if all entries are valid before allowing new entry addition
validateBeforeAddWhitelist() { validateBeforeAddWhitelist() {
//console.log('=== validateBeforeAddWhitelist START ===');
// Simple test - just check for empty entries // Simple test - just check for empty entries
const allInputs = document.querySelectorAll('input[name="CFG_IPS_WHITELIST"]:not([type="hidden"])'); const allInputs = document.querySelectorAll('input[name="CFG_IPS_WHITELIST"]:not([type="hidden"])');
//console.log('Found', allInputs.length, 'inputs');
allInputs.forEach((input, index) => { allInputs.forEach((input, index) => {
//console.log(`Input ${index}: value="${input.value}"`);
}); });
for (const input of allInputs) { for (const input of allInputs) {
@ -465,7 +420,6 @@ class IPWhitelistManager {
// Check if entry is empty // Check if entry is empty
if (!entryValue) { if (!entryValue) {
//console.log('Found empty entry - blocking add');
// Flash the empty input field // Flash the empty input field
input.style.animation = 'whitelist-flash 0.5s ease-in-out 2'; input.style.animation = 'whitelist-flash 0.5s ease-in-out 2';
input.focus(); input.focus();
@ -477,26 +431,20 @@ class IPWhitelistManager {
if (window.notificationSystem) { if (window.notificationSystem) {
window.notificationSystem.error('Whitelist entry cannot be empty'); window.notificationSystem.error('Whitelist entry cannot be empty');
} }
//console.log('=== validateBeforeAddWhitelist END (false - empty) ===');
return false; return false;
} }
// Check entry format with notification (always show) // Check entry format with notification (always show)
if (this.checkForInvalidWhitelistFormat(input, entryValue, false)) { if (this.checkForInvalidWhitelistFormat(input, entryValue, false)) {
//console.log('Found invalid format - blocking add');
//console.log('=== validateBeforeAddWhitelist END (false - invalid) ===');
return false; return false;
} }
// Check for duplicates with notification (always show) // Check for duplicates with notification (always show)
if (this.checkForDuplicateWhitelistEntry(input, entryValue)) { if (this.checkForDuplicateWhitelistEntry(input, entryValue)) {
//console.log('Found duplicate entry - blocking add');
//console.log('=== validateBeforeAddWhitelist END (false - duplicate) ===');
return false; return false;
} }
} }
//console.log('=== validateBeforeAddWhitelist END (true) ===');
return true; return true;
} }
@ -550,12 +498,6 @@ class IPWhitelistManager {
const isValidIP = ipPattern.test(entryValue) || ipv6Pattern.test(entryValue); const isValidIP = ipPattern.test(entryValue) || ipv6Pattern.test(entryValue);
const isValidDomain = domainPattern.test(entryValue); const isValidDomain = domainPattern.test(entryValue);
//console.log('checkForInvalidWhitelistFormat validation:', {
//entryValue: entryValue,
//isValidIP: isValidIP,
//isValidDomain: isValidDomain,
//isValidFormat: isValidIP || isValidDomain || entryValue.toLowerCase() === 'localhost'
//});
if (!isValidIP && !isValidDomain) { if (!isValidIP && !isValidDomain) {
// Flash the input field // Flash the input field
@ -579,7 +521,6 @@ class IPWhitelistManager {
// Delete whitelist entry // Delete whitelist entry
deleteWhitelistEntry(entryIndex, buttonElement) { deleteWhitelistEntry(entryIndex, buttonElement) {
//console.log(`Delete whitelist entry button clicked for index: ${entryIndex}`);
try { try {
// Get the actual whitelist number from the input ID // Get the actual whitelist number from the input ID
@ -599,7 +540,6 @@ class IPWhitelistManager {
const match = inputId.match(/config-CFG_IPS_WHITELIST_(\d+)/); const match = inputId.match(/config-CFG_IPS_WHITELIST_(\d+)/);
const whitelistNumber = match ? parseInt(match[1]) : 0; const whitelistNumber = match ? parseInt(match[1]) : 0;
//console.log(`Actual whitelist number: ${whitelistNumber}`);
// Find all whitelist numbers to determine the highest // Find all whitelist numbers to determine the highest
const allBlocks = document.querySelectorAll('.whitelist-building-block'); const allBlocks = document.querySelectorAll('.whitelist-building-block');
@ -616,11 +556,9 @@ class IPWhitelistManager {
}); });
const highestNumber = Math.max(...allNumbers); const highestNumber = Math.max(...allNumbers);
//console.log(`Highest whitelist number: ${highestNumber}`);
// Only allow deletion if this is the highest numbered entry AND it's not #1 // Only allow deletion if this is the highest numbered entry AND it's not #1
if (whitelistNumber === 1) { if (whitelistNumber === 1) {
//console.log('Cannot delete entry #1');
if (window.notificationSystem) { if (window.notificationSystem) {
window.notificationSystem.error('Entry 1 cannot be deleted'); window.notificationSystem.error('Entry 1 cannot be deleted');
} }
@ -628,7 +566,6 @@ class IPWhitelistManager {
} }
if (whitelistNumber !== highestNumber) { if (whitelistNumber !== highestNumber) {
//console.log('Can only delete the highest numbered entry');
if (window.notificationSystem) { if (window.notificationSystem) {
window.notificationSystem.error('Can only delete the highest numbered entry'); window.notificationSystem.error('Can only delete the highest numbered entry');
} }
@ -640,7 +577,6 @@ class IPWhitelistManager {
// Remove the building block from DOM // Remove the building block from DOM
entryBlock.remove(); entryBlock.remove();
//console.log('Removed entry block from DOM');
// Update the hidden input with remaining values // Update the hidden input with remaining values
this.saveWhitelistEntries(); this.saveWhitelistEntries();
@ -827,7 +763,6 @@ function checkForDuplicateWhitelistEntry(input, entryValue) {
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Whitelist entry already exists'; input.title = 'Whitelist entry already exists';
if (window.notificationSystem) { if (window.notificationSystem) {
//console.log('Showing duplicate whitelist entry notification');
window.notificationSystem.error('Whitelist entry "' + entryValue + '" already exists'); window.notificationSystem.error('Whitelist entry "' + entryValue + '" already exists');
} else { } else {
console.error('Whitelist entry already exists - notification system not available'); console.error('Whitelist entry already exists - notification system not available');
@ -855,7 +790,6 @@ function checkForInvalidWhitelistFormat(input, entryValue) {
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Invalid IP address or domain format (e.g., 192.168.1.100 or example.com)'; input.title = 'Invalid IP address or domain format (e.g., 192.168.1.100 or example.com)';
if (window.notificationSystem) { if (window.notificationSystem) {
//console.log('Showing invalid whitelist format notification');
window.notificationSystem.error('Invalid whitelist format: "' + entryValue + '". Please use a valid IP address or domain like 192.168.1.100 or example.com'); window.notificationSystem.error('Invalid whitelist format: "' + entryValue + '". Please use a valid IP address or domain like 192.168.1.100 or example.com');
} else { } else {
console.error('Invalid whitelist format - notification system not available'); console.error('Invalid whitelist format - notification system not available');
@ -869,15 +803,12 @@ function checkForInvalidWhitelistFormat(input, entryValue) {
// Validate whitelist entry format when user tries to add a new entry // Validate whitelist entry format when user tries to add a new entry
function validateWhitelistEntry(input, showNotifications = true) { function validateWhitelistEntry(input, showNotifications = true) {
const value = input.value.trim(); const value = input.value.trim();
//console.log('validateWhitelistEntry called with:', value, 'showNotifications:', showNotifications);
//console.log('window.notificationSystem available:', !!window.notificationSystem);
if (!value) { if (!value) {
// Clear styling for empty fields // Clear styling for empty fields
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Whitelist entry cannot be empty'; input.title = 'Whitelist entry cannot be empty';
if (showNotifications && window.notificationSystem) { if (showNotifications && window.notificationSystem) {
//console.log('Attempting to show empty whitelist notification');
window.notificationSystem.error('Whitelist entry cannot be empty'); window.notificationSystem.error('Whitelist entry cannot be empty');
} else { } else {
console.error('Whitelist entry cannot be empty - notification system not available'); console.error('Whitelist entry cannot be empty - notification system not available');
@ -905,7 +836,6 @@ function validateWhitelistEntry(input, showNotifications = true) {
input.style.borderColor = '#dc3545'; input.style.borderColor = '#dc3545';
input.title = 'Invalid IP address, domain, or localhost format (e.g., 192.168.1.100, example.com, or localhost)'; input.title = 'Invalid IP address, domain, or localhost format (e.g., 192.168.1.100, example.com, or localhost)';
if (showNotifications && window.notificationSystem) { if (showNotifications && window.notificationSystem) {
//console.log('Attempting to show invalid whitelist format notification');
window.notificationSystem.error('Invalid whitelist format: "' + value + '". Please use a valid IP address, domain, or localhost like 192.168.1.100, example.com, or localhost'); window.notificationSystem.error('Invalid whitelist format: "' + value + '". Please use a valid IP address, domain, or localhost like 192.168.1.100, example.com, or localhost');
} else { } else {
console.error('Invalid whitelist format - notification system not available'); console.error('Invalid whitelist format - notification system not available');

View File

@ -6,19 +6,15 @@ class ToggleManager {
} }
init() { init() {
//console.log('ToggleManager: Initializing...');
// Auto-discover all toggle configurations // Auto-discover all toggle configurations
this.discoverToggles(); this.discoverToggles();
//console.log('ToggleManager: Discovered', this.toggles.size, 'toggle configurations');
// Debug: Log discovered toggles // Debug: Log discovered toggles
if (this.toggles.size > 0) { if (this.toggles.size > 0) {
//console.log('ToggleManager: No toggles found - will retry after config loads...');
// Set up a mutation observer to detect when config content is added // Set up a mutation observer to detect when config content is added
this.setupContentObserver(); this.setupContentObserver();
} else { } else {
//console.log('ToggleManager: Discovered toggles:', Array.from(this.toggles.keys()));
} }
// Also set up observer in case more toggles are added later // Also set up observer in case more toggles are added later
@ -26,7 +22,6 @@ class ToggleManager {
// Retry discovery after a short delay to handle timing issues // Retry discovery after a short delay to handle timing issues
setTimeout(() => { setTimeout(() => {
//console.log('ToggleManager: Retrying toggle discovery...');
this.rediscoverToggles(); this.rediscoverToggles();
}, 100); }, 100);
} }
@ -40,7 +35,6 @@ class ToggleManager {
const newToggles = Array.from(mutation.addedNodes).filter(node => node.nodeType === Node.ELEMENT_NODE && (node.dataset?.toggleConfig || node.querySelector('[data-toggle-config]'))); const newToggles = Array.from(mutation.addedNodes).filter(node => node.nodeType === Node.ELEMENT_NODE && (node.dataset?.toggleConfig || node.querySelector('[data-toggle-config]')));
if (newToggles.length > 0) { if (newToggles.length > 0) {
//console.log('ToggleManager: New toggle elements detected, re-discovering...');
this.rediscoverToggles(); this.rediscoverToggles();
observer.disconnect(); // Stop observing once we find toggles observer.disconnect(); // Stop observing once we find toggles
} }
@ -60,35 +54,24 @@ class ToggleManager {
// Re-discover toggles (called after content is loaded) // Re-discover toggles (called after content is loaded)
rediscoverToggles() { rediscoverToggles() {
//console.log('ToggleManager: Re-discovering toggles...');
this.toggles.clear(); // Clear existing toggles this.toggles.clear(); // Clear existing toggles
this.discoverToggles(); this.discoverToggles();
//console.log('ToggleManager: Re-discovered', this.toggles.size, 'toggle configurations');
if (this.toggles.size > 0) { if (this.toggles.size > 0) {
//console.log('ToggleManager: Successfully discovered toggles:', Array.from(this.toggles.keys()));
} }
} }
// Auto-discover toggle configurations from the page // Auto-discover toggle configurations from the page
discoverToggles() { discoverToggles() {
//console.log('ToggleManager: Looking for elements with [data-toggle-config]...');
// Find all elements with data-toggle-config attribute // Find all elements with data-toggle-config attribute
const toggleElements = document.querySelectorAll('[data-toggle-config]'); const toggleElements = document.querySelectorAll('[data-toggle-config]');
//console.log('ToggleManager: Found', toggleElements.length, 'elements with data-toggle-config');
toggleElements.forEach((element, index) => { toggleElements.forEach((element, index) => {
const config = element.dataset.toggleConfig; const config = element.dataset.toggleConfig;
const sectionId = element.dataset.sectionId; const sectionId = element.dataset.sectionId;
const toggleType = element.dataset.toggleType || 'checkbox'; const toggleType = element.dataset.toggleType || 'checkbox';
//console.log(`ToggleManager: Processing element ${index}:`, {
//config: config,
//sectionId: sectionId,
//toggleType: toggleType,
//element: element.tagName + (element.id ? '#' + element.id : '') + (element.name ? '[name=' + element.name + ']' : '')
//});
if (config && sectionId) { if (config && sectionId) {
this.toggles.set(config, { this.toggles.set(config, {
@ -97,18 +80,13 @@ class ToggleManager {
toggleType: toggleType, toggleType: toggleType,
element: element element: element
}); });
//console.log(`ToggleManager: Registered toggle for config: ${config}`);
} else { } else {
//console.log(`ToggleManager: Skipping element - missing config or sectionId`);
} }
}); });
} }
// Universal toggle function - works for any config option // Universal toggle function - works for any config option
toggle(configKey, isEnabled) { toggle(configKey, isEnabled) {
//console.log('=== TOGGLE MANAGER DEBUG ===');
//console.log('configKey:', configKey);
//console.log('isEnabled:', isEnabled);
const toggle = this.toggles.get(configKey); const toggle = this.toggles.get(configKey);
if (!toggle) { if (!toggle) {
@ -116,20 +94,15 @@ class ToggleManager {
return false; return false;
} }
//console.log('Toggle found:', toggle);
const sectionContent = document.getElementById(toggle.sectionId); const sectionContent = document.getElementById(toggle.sectionId);
const fields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea'); const fields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
//console.log('sectionContent found:', !!sectionContent);
//console.log('fields found:', fields ? fields.length : 0);
if (sectionContent && fields) { if (sectionContent && fields) {
if (isEnabled) { if (isEnabled) {
//console.log('Enabling section...');
sectionContent.classList.remove('hidden'); sectionContent.classList.remove('hidden');
fields.forEach((field, index) => { fields.forEach((field, index) => {
//console.log(`Enabling field ${index}:`, field);
field.disabled = false; field.disabled = false;
const fieldGroup = field?.closest('.field-group'); const fieldGroup = field?.closest('.field-group');
if (fieldGroup) { if (fieldGroup) {
@ -138,10 +111,8 @@ class ToggleManager {
} }
}); });
} else { } else {
//console.log('Disabling section...');
sectionContent.classList.add('hidden'); sectionContent.classList.add('hidden');
fields.forEach((field, index) => { fields.forEach((field, index) => {
//console.log(`Disabling field ${index}:`, field);
field.disabled = true; field.disabled = true;
const fieldGroup = field?.closest('.field-group'); const fieldGroup = field?.closest('.field-group');
if (fieldGroup) { if (fieldGroup) {
@ -151,7 +122,6 @@ class ToggleManager {
}); });
} }
//console.log('=== TOGGLE MANAGER SUCCESS ===');
return true; return true;
} else { } else {
console.error('ToggleManager: Section content or fields not found'); console.error('ToggleManager: Section content or fields not found');
@ -300,7 +270,6 @@ window.toggleManager.renderToggleSection = ToggleManager.renderToggleSection;
// Add method to manually trigger discovery when config is loaded // Add method to manually trigger discovery when config is loaded
window.toggleManager.forceRediscover = function() { window.toggleManager.forceRediscover = function() {
//console.log('ToggleManager: Force re-discovering toggles...');
window.toggleManager.rediscoverToggles(); window.toggleManager.rediscoverToggles();
}; };

View File

@ -3,9 +3,6 @@
class AppTabbedManager { class AppTabbedManager {
constructor() { constructor() {
// console.log('🔍 AppTabbedManager constructor called');
// console.log('🔍 URL in constructor:', window.location.href);
// console.log('🔍 Search params in constructor:', window.location.search);
// Store original URL for task parameter detection // Store original URL for task parameter detection
this.originalUrl = window.location.href; this.originalUrl = window.location.href;
@ -13,22 +10,18 @@ class AppTabbedManager {
// Check sessionStorage for task parameter (fallback) // Check sessionStorage for task parameter (fallback)
const sessionTaskId = sessionStorage.getItem('pendingTaskId'); const sessionTaskId = sessionStorage.getItem('pendingTaskId');
// console.log('🔍 Session storage task ID:', sessionTaskId);
// Debug: Check if task parameter exists in original URL // Debug: Check if task parameter exists in original URL
const originalParams = new URLSearchParams(this.originalSearch); const originalParams = new URLSearchParams(this.originalSearch);
const originalTaskId = originalParams.get('task'); const originalTaskId = originalParams.get('task');
// console.log('🔍 Original task ID in constructor:', originalTaskId);
// Try to get task parameter from performance navigation if available // Try to get task parameter from performance navigation if available
if (performance && performance.getEntriesByType) { if (performance && performance.getEntriesByType) {
const navigationEntries = performance.getEntriesByType('navigation'); const navigationEntries = performance.getEntriesByType('navigation');
if (navigationEntries.length > 0) { if (navigationEntries.length > 0) {
const navEntry = navigationEntries[0]; const navEntry = navigationEntries[0];
// console.log('🔍 Navigation entry URL:', navEntry.name);
const navParams = new URLSearchParams(new URL(navEntry.name).search); const navParams = new URLSearchParams(new URL(navEntry.name).search);
const navTaskId = navParams.get('task'); const navTaskId = navParams.get('task');
// console.log('🔍 Navigation task ID:', navTaskId);
} }
} }
@ -69,7 +62,6 @@ class AppTabbedManager {
setCurrentApp(appName) { setCurrentApp(appName) {
if (this.currentApp === appName) return; if (this.currentApp === appName) return;
// console.log('🔄 setCurrentApp: switching from %s to %s', this.currentApp, appName);
this.currentApp = appName; this.currentApp = appName;
// Before clearing disabled button references, restore any static backup action buttons // Before clearing disabled button references, restore any static backup action buttons
@ -89,7 +81,6 @@ class AppTabbedManager {
this.enableTabs(); this.enableTabs();
const running = this.getRunningTaskForApp(appName); const running = this.getRunningTaskForApp(appName);
// console.log('🔍 setCurrentApp: running task for %s = %o', appName, running);
if (running) { if (running) {
this.activeTaskId = running.taskId; this.activeTaskId = running.taskId;
} }
@ -109,7 +100,6 @@ class AppTabbedManager {
} }
} }
// console.log('🔍 Original app name from URL:', appName);
// Convert full app name to slug for task filtering // Convert full app name to slug for task filtering
if (appName && window.apps) { if (appName && window.apps) {
@ -124,14 +114,11 @@ class AppTabbedManager {
const command = appData.command || ''; const command = appData.command || '';
const parts = command.split(' '); const parts = command.split(' ');
const slug = parts[parts.length - 1]; // Return the slug const slug = parts[parts.length - 1]; // Return the slug
// console.log('🔄 Converted to slug:', slug, 'from appData:', appData.name);
return slug; return slug;
} else { } else {
// console.log('⚠️ No app data found for:', appName);
} }
} }
// console.log('🔄 Returning original app name:', appName);
return appName; return appName;
} }
@ -210,10 +197,6 @@ class AppTabbedManager {
// Switch between tabs // Switch between tabs
switchTab(tabId) { switchTab(tabId) {
// console.log('🔄 switchTab called with:', tabId);
// console.log('🔍 Current currentApp before switch:', this.currentApp);
// console.log('🔍 Current URL when switching:', window.location.href);
// console.log('🔍 URL search when switching:', window.location.search);
// Remove active class from all main navigation tabs // Remove active class from all main navigation tabs
document.querySelectorAll('.main-tab-button').forEach(btn => { document.querySelectorAll('.main-tab-button').forEach(btn => {
@ -245,12 +228,10 @@ class AppTabbedManager {
// Update URL (only tab, not app) - but only on app pages // Update URL (only tab, not app) - but only on app pages
if (this.isAppPage()) { if (this.isAppPage()) {
// console.log('🔄 About to updateURL with tab:', tabId);
this.updateURL(null, tabId); this.updateURL(null, tabId);
} }
// Load tab-specific content // Load tab-specific content
// console.log('🔄 About to load tab content for tab:', tabId, 'with currentApp:', this.currentApp);
this.loadTabContent(tabId); this.loadTabContent(tabId);
} }
@ -259,8 +240,6 @@ class AppTabbedManager {
const actualTabId = tabId === 'logs' ? 'tasks' : tabId; const actualTabId = tabId === 'logs' ? 'tasks' : tabId;
const currentAppFromUrl = this.getAppFromURL(); const currentAppFromUrl = this.getAppFromURL();
// console.log('📂 loadTabContent: tabId=%s, currentApp=%s, fromUrl=%s',
// tabId, this.currentApp, currentAppFromUrl);
// Update currentApp if URL has different app name. Route through setCurrentApp // Update currentApp if URL has different app name. Route through setCurrentApp
// so any disable state from the previous app gets cleared before we render. // so any disable state from the previous app gets cleared before we render.
@ -297,7 +276,6 @@ class AppTabbedManager {
// Make sure app detail view is visible and app is loaded // Make sure app detail view is visible and app is loaded
if (window.appsManager) { if (window.appsManager) {
// Use showAppDetail to ensure proper initialization (same as config tab) // Use showAppDetail to ensure proper initialization (same as config tab)
// console.log('🔄 Ensuring app detail is loaded for:', this.currentApp);
window.appsManager.showAppDetail(this.currentApp); window.appsManager.showAppDetail(this.currentApp);
// Wait a bit for DOM to be ready after app detail is rendered // Wait a bit for DOM to be ready after app detail is rendered
@ -306,11 +284,9 @@ class AppTabbedManager {
switch (actualTabId) { switch (actualTabId) {
case 'tasks': case 'tasks':
// console.log('🔄 loadTabContent: Loading tasks for app:', this.currentApp);
await this.loadAppTasks(); await this.loadAppTasks();
break; break;
case 'backups': case 'backups':
// console.log('🔄 loadTabContent: Loading backups for app:', this.currentApp);
await this.loadAppBackups(); await this.loadAppBackups();
// IMPORTANT: Re-apply button state if there are running tasks // IMPORTANT: Re-apply button state if there are running tasks
this.restoreButtonState(); this.restoreButtonState();
@ -335,7 +311,6 @@ class AppTabbedManager {
break; break;
case 'config': case 'config':
// Config is already handled by showAppDetail above // Config is already handled by showAppDetail above
// console.log('🔧 Config content already loaded by showAppDetail');
// IMPORTANT: Re-apply button state if there are running tasks // IMPORTANT: Re-apply button state if there are running tasks
this.restoreButtonState(); this.restoreButtonState();
break; break;
@ -355,7 +330,6 @@ class AppTabbedManager {
// Load tasks specific to current app // Load tasks specific to current app
async loadAppTasks() { async loadAppTasks() {
// console.log('🔄 loadAppTasks called, currentApp:', this.currentApp);
// Show loading spinner by showing the initial loading state // Show loading spinner by showing the initial loading state
const tasksContainer = document.getElementById('app-tasks'); const tasksContainer = document.getElementById('app-tasks');
@ -398,32 +372,20 @@ class AppTabbedManager {
try { try {
// Load all tasks // Load all tasks
// console.log('🔄 Loading tasks...');
// console.log('🔍 Using currentApp for filtering:', this.currentApp);
await this.tasksManager.loadTasks(); await this.tasksManager.loadTasks();
const allTasks = this.tasksManager.tasks || []; const allTasks = this.tasksManager.tasks || [];
// console.log('📊 All tasks loaded:', allTasks.length);
// console.log('📋 All tasks data:', allTasks);
// console.log('📋 Sample task app names:', allTasks.slice(0, 3).map(t => t.app));
// Filter tasks for current app // Filter tasks for current app
const appTasks = allTasks.filter(task => task.app === this.currentApp); const appTasks = allTasks.filter(task => task.app === this.currentApp);
// console.log('🎯 Filtering tasks for app:', this.currentApp);
// console.log('📋 Available task.app values:', [...new Set(allTasks.map(t => t.app))]);
// console.log('🎯 Filtered tasks for', this.currentApp, ':', appTasks.length);
// Debug: Show what would match if we used different app names // Debug: Show what would match if we used different app names
// console.log('🔍 Debug - Testing different app names:');
['libreportal', 'fail2ban', 'LibrePortal', 'Fail2Ban'].forEach(testApp => { ['libreportal', 'fail2ban', 'LibrePortal', 'Fail2Ban'].forEach(testApp => {
const testTasks = allTasks.filter(task => task.app === testApp); const testTasks = allTasks.filter(task => task.app === testApp);
// console.log(` - "${testApp}": ${testTasks.length} tasks`);
}); });
if (appTasks.length === 0) { if (appTasks.length === 0) {
// console.log('⚠️ No tasks found for', this.currentApp, '- checking if tasks have different app names');
// Show some task details for debugging // Show some task details for debugging
if (allTasks.length > 0) { if (allTasks.length > 0) {
// console.log('📋 Sample tasks:', allTasks.slice(0, 3).map(t => ({ id: t.id, app: t.app, command: t.command })));
} }
tasksContainer.innerHTML = `<p style="color: #888;">No tasks found for ${this.currentApp}.</p>`; tasksContainer.innerHTML = `<p style="color: #888;">No tasks found for ${this.currentApp}.</p>`;
return; return;
@ -441,10 +403,8 @@ class AppTabbedManager {
// Handle pending task ID from URL parameter // Handle pending task ID from URL parameter
if (this.pendingTaskId) { if (this.pendingTaskId) {
// console.log('🔍 Handling pending task ID after tasks loaded:', this.pendingTaskId);
setTimeout(() => { setTimeout(() => {
if (typeof window.toggleAppTaskDetails === 'function') { if (typeof window.toggleAppTaskDetails === 'function') {
// console.log('🔍 Opening task details for pending task:', this.pendingTaskId);
window.toggleAppTaskDetails(this.pendingTaskId); window.toggleAppTaskDetails(this.pendingTaskId);
// Scroll to the task element after opening details // Scroll to the task element after opening details
@ -466,7 +426,6 @@ class AppTabbedManager {
// Scroll to specific task element with smooth animation // Scroll to specific task element with smooth animation
scrollToTask(taskId) { scrollToTask(taskId) {
// console.log('🔍 Scrolling to task:', taskId);
// Find the task element by ID or data attribute // Find the task element by ID or data attribute
let taskElement = document.getElementById(`task-${taskId}`); let taskElement = document.getElementById(`task-${taskId}`);
@ -485,7 +444,6 @@ class AppTabbedManager {
} }
if (taskElement) { if (taskElement) {
// console.log('🔍 Found task element, scrolling to it:', taskElement);
// Smooth scroll to the task element // Smooth scroll to the task element
taskElement.scrollIntoView({ taskElement.scrollIntoView({
@ -511,7 +469,6 @@ class AppTabbedManager {
setupAppTaskFunctions() { setupAppTaskFunctions() {
// Create app-specific toggleTaskDetails function // Create app-specific toggleTaskDetails function
window.toggleAppTaskDetails = (taskId) => { window.toggleAppTaskDetails = (taskId) => {
// console.log('🔍 App-specific toggleTaskDetails called for:', taskId);
const details = document.getElementById(`details-${taskId}`); const details = document.getElementById(`details-${taskId}`);
const toggleBtn = document.querySelector(`.task-btn.toggle-details[onclick*="toggleTaskDetails('${taskId}')"]`); const toggleBtn = document.querySelector(`.task-btn.toggle-details[onclick*="toggleTaskDetails('${taskId}')"]`);
@ -599,11 +556,9 @@ class AppTabbedManager {
async initialize() { async initialize() {
// Prevent double initialization // Prevent double initialization
if (this.initialized) { if (this.initialized) {
// console.log('⚠️ AppTabbedManager already initialized, skipping');
return; return;
} }
// console.log('🚀 AppTabbedManager initializing, currentApp:', this.currentApp);
// Initialize task system if not already done (with retry) // Initialize task system if not already done (with retry)
if (this.tasksManager && !this.tasksManager.commands) { if (this.tasksManager && !this.tasksManager.commands) {
@ -612,11 +567,9 @@ class AppTabbedManager {
const maxAttempts = 5; const maxAttempts = 5;
while (!initialized && attempts < maxAttempts) { while (!initialized && attempts < maxAttempts) {
// console.log(`🔄 Attempting to initialize task system (${attempts + 1}/${maxAttempts})...`);
try { try {
initialized = this.tasksManager.initializeTaskSystem(); initialized = this.tasksManager.initializeTaskSystem();
if (initialized) { if (initialized) {
// console.log('✅ Task system initialized successfully');
} }
} catch (error) { } catch (error) {
console.error('❌ Task system initialization error:', error); console.error('❌ Task system initialization error:', error);
@ -670,7 +623,6 @@ class AppTabbedManager {
// Set current app from URL BEFORE setting up URL monitoring // Set current app from URL BEFORE setting up URL monitoring
const urlAppName = this.getAppFromURL(); const urlAppName = this.getAppFromURL();
// console.log('🔍 Setting initial currentApp from URL:', urlAppName);
this.currentApp = urlAppName; this.currentApp = urlAppName;
// Check for running tasks for this app and auto-switch to tasks tab if found // Check for running tasks for this app and auto-switch to tasks tab if found
@ -686,22 +638,17 @@ class AppTabbedManager {
// Check for task parameter and handle it AFTER tasks are loaded // Check for task parameter and handle it AFTER tasks are loaded
// Use original URL since the current URL might have been modified // Use original URL since the current URL might have been modified
const urlParams = new URLSearchParams(this.originalSearch); const urlParams = new URLSearchParams(this.originalSearch);
// console.log('🔍 Original URL search during init:', this.originalSearch);
// console.log('🔍 Original URL params during init:', Object.fromEntries(urlParams.entries()));
let taskId = urlParams.get('task'); let taskId = urlParams.get('task');
// console.log('🔍 Task ID from original params:', taskId);
// Fallback: Check sessionStorage if URL doesn't have task parameter // Fallback: Check sessionStorage if URL doesn't have task parameter
if (!taskId) { if (!taskId) {
taskId = sessionStorage.getItem('pendingTaskId'); taskId = sessionStorage.getItem('pendingTaskId');
// console.log('🔍 Task ID from sessionStorage fallback:', taskId);
// Clear sessionStorage after using it // Clear sessionStorage after using it
if (taskId) { if (taskId) {
sessionStorage.removeItem('pendingTaskId'); sessionStorage.removeItem('pendingTaskId');
} }
} }
if (taskId) { if (taskId) {
// console.log('🔍 Task parameter found:', taskId);
// Store the task ID to handle after tasks are loaded // Store the task ID to handle after tasks are loaded
this.pendingTaskId = taskId; this.pendingTaskId = taskId;
// Force tasks tab // Force tasks tab
@ -722,7 +669,6 @@ class AppTabbedManager {
// Set initial active tab (only if no task parameter) // Set initial active tab (only if no task parameter)
if (!taskId) { if (!taskId) {
const initialTab = this.getTabFromURL(); const initialTab = this.getTabFromURL();
// console.log('🔄 Setting initial tab:', initialTab, 'with currentApp:', this.currentApp);
this.switchTab(initialTab); this.switchTab(initialTab);
} }
@ -739,7 +685,6 @@ class AppTabbedManager {
const newAppName = this.getAppFromURL(); const newAppName = this.getAppFromURL();
// Only update if currentApp is already set and app actually changed // Only update if currentApp is already set and app actually changed
if (this.currentApp && newAppName !== this.currentApp) { if (this.currentApp && newAppName !== this.currentApp) {
// console.log('🔄 URL changed, updating app from', this.currentApp, 'to', newAppName);
this.updateApp(newAppName); this.updateApp(newAppName);
} }
}); });
@ -776,7 +721,6 @@ class AppTabbedManager {
// Create backup (placeholder function) // Create backup (placeholder function)
async createBackup(appName) { async createBackup(appName) {
// Placeholder - will be implemented with actual backup logic // Placeholder - will be implemented with actual backup logic
// console.log(`Creating backup for ${appName}...`);
} }
// Setup task event listeners for button state management // Setup task event listeners for button state management
@ -785,8 +729,6 @@ class AppTabbedManager {
const { taskId, appName, action } = event.detail; const { taskId, appName, action } = event.detail;
const key = this.taskKey(appName, action); const key = this.taskKey(appName, action);
// console.log('📌 taskCreated: appName=%s, currentApp=%s, action=%s, key=%s',
// appName, this.currentApp, action, key);
if (this.runningTasks.has(key)) { if (this.runningTasks.has(key)) {
const existing = this.runningTasks.get(key); const existing = this.runningTasks.get(key);
@ -818,7 +760,6 @@ class AppTabbedManager {
} }
this.runningTasks.set(key, { taskId, appName, action }); this.runningTasks.set(key, { taskId, appName, action });
// console.log('📌 taskCreated: stored in runningTasks, will disable=%s', appName === this.currentApp);
if (appName === this.currentApp) { if (appName === this.currentApp) {
this.disableAppButtons(appName, action); this.disableAppButtons(appName, action);
@ -924,8 +865,6 @@ class AppTabbedManager {
// Disable app buttons during task execution // Disable app buttons during task execution
disableAppButtons(appName, action) { disableAppButtons(appName, action) {
// console.log('🚫 disableAppButtons called: appName=%s, action=%s, currentApp=%s',
// appName, action, this.currentApp);
// Also disable config and backup tabs // Also disable config and backup tabs
this.disableTabs(); this.disableTabs();
@ -940,7 +879,6 @@ class AppTabbedManager {
// Disable ALL buttons in the app content section // Disable ALL buttons in the app content section
const allButtons = appContent.querySelectorAll('button:not([disabled]):not(.tab-button)'); const allButtons = appContent.querySelectorAll('button:not([disabled]):not(.tab-button)');
// console.log('🚫 disableAppButtons found %d buttons to disable', allButtons.length);
allButtons.forEach(button => { allButtons.forEach(button => {
// Skip tab buttons (config, backup, tasks tabs) // Skip tab buttons (config, backup, tasks tabs)
@ -978,7 +916,6 @@ class AppTabbedManager {
tempDiv.innerHTML = originalContent; tempDiv.innerHTML = originalContent;
const textContent = tempDiv.textContent || tempDiv.innerText || originalContent; const textContent = tempDiv.textContent || tempDiv.innerText || originalContent;
// console.log('🔃 Adding spinner to button:', button.textContent.trim(), 'for app:', appName);
button.innerHTML = ` button.innerHTML = `
<span class="spinner" style=" <span class="spinner" style="
display: inline-block; display: inline-block;
@ -1001,7 +938,6 @@ class AppTabbedManager {
this.disabledButtons.add(button); this.disabledButtons.add(button);
}); });
// console.log(`🔍 Disabled ${allButtons.length} buttons for ${appName} during ${action}`);
} }
// Restore button state when switching tabs. Only disable if the *current* app // Restore button state when switching tabs. Only disable if the *current* app
@ -1092,12 +1028,10 @@ window.AppTabbedManager = AppTabbedManager;
// Initialize when DOM is loaded // Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', async () => { document.addEventListener('DOMContentLoaded', async () => {
// console.log('🔍 DOMContentLoaded: Skipping automatic initialization - SPA will handle it');
// Don't initialize here - let SPA handle it // Don't initialize here - let SPA handle it
}); });
// Also initialize when scripts are loaded (for SPA navigation) // Also initialize when scripts are loaded (for SPA navigation)
window.addEventListener('load', async () => { window.addEventListener('load', async () => {
// console.log('🔍 Window load: Skipping automatic initialization - SPA will handle it');
// Don't initialize here - let SPA handle it // Don't initialize here - let SPA handle it
}); });

View File

@ -206,7 +206,6 @@ class AppsManager {
if (response.ok) { if (response.ok) {
const appsData = await response.json(); const appsData = await response.json();
window.apps = appsData.apps || []; window.apps = appsData.apps || [];
// console.log(`✅ Reloaded ${window.apps.length} apps`);
} }
} catch (error) { } catch (error) {
console.error('❌ Failed to reload apps data:', error); console.error('❌ Failed to reload apps data:', error);
@ -340,7 +339,6 @@ class AppsManager {
} }
showAppDetail(appName, forceConfigTab = false) { showAppDetail(appName, forceConfigTab = false) {
// console.log('🔍 showAppDetail called with:', { appName, forceConfigTab });
//// // console.log(`AppsManager: Showing app detail: ${appName}`); //// // console.log(`AppsManager: Showing app detail: ${appName}`);
// Don't proceed if appName is empty - redirect to apps list instead // Don't proceed if appName is empty - redirect to apps list instead
@ -362,12 +360,10 @@ class AppsManager {
if (forceConfigTab) { if (forceConfigTab) {
// Force config tab for install/manage buttons // Force config tab for install/manage buttons
targetTab = 'config'; targetTab = 'config';
// console.log('🔍 Forcing config tab due to forceConfigTab=true');
} else { } else {
// Preserve existing tab or default to config for direct navigation // Preserve existing tab or default to config for direct navigation
const currentUrl = new URL(window.location.href); const currentUrl = new URL(window.location.href);
targetTab = currentUrl.searchParams.get('tab') || 'config'; targetTab = currentUrl.searchParams.get('tab') || 'config';
// console.log('🔍 Preserving existing tab:', targetTab);
} }
const newUrl = window.appPath(appName, targetTab); const newUrl = window.appPath(appName, targetTab);
@ -411,8 +407,6 @@ class AppsManager {
// Show app detail with config tab (for install/manage buttons) // Show app detail with config tab (for install/manage buttons)
showAppDetailWithConfig(appName) { showAppDetailWithConfig(appName) {
// console.log('🔍 showAppDetailWithConfig called with:', appName);
// console.log('🔍 Forcing config tab for button click');
// Check if there's a running task for this app — switch straight to the tasks // Check if there's a running task for this app — switch straight to the tasks
// tab if so, instead of landing on config (whose buttons would be disabled). // tab if so, instead of landing on config (whose buttons would be disabled).
@ -440,7 +434,6 @@ class AppsManager {
} }
// Simulate clicking target tab functionally // Simulate clicking target tab functionally
// console.log('🔄 Simulating target tab click:', targetTab);
setTimeout(() => { setTimeout(() => {
window.appTabbedManager.switchTab(targetTab); window.appTabbedManager.switchTab(targetTab);
// Highlight the running task if switching to tasks tab // Highlight the running task if switching to tasks tab
@ -1438,7 +1431,6 @@ class AppsManager {
} else if (window.librePortalSPA) { } else if (window.librePortalSPA) {
// Fallback: navigate to app with tasks tab // Fallback: navigate to app with tasks tab
const taskUrl = window.appPath(appName, 'tasks', null, task ? task.id : null); const taskUrl = window.appPath(appName, 'tasks', null, task ? task.id : null);
// console.log(`🔄 Navigating to app tasks with uninstall task: ${task?.id}`);
window.librePortalSPA.navigateTo(taskUrl); window.librePortalSPA.navigateTo(taskUrl);
} else if (window.navigateToRoute) { } else if (window.navigateToRoute) {
window.navigateToRoute(window.appPath(appName, 'tasks', null, task ? task.id : null).replace(/^\//, '')); window.navigateToRoute(window.appPath(appName, 'tasks', null, task ? task.id : null).replace(/^\//, ''));
@ -1513,7 +1505,6 @@ class AppsManager {
`; `;
} }
// console.log(`🔍 Install button disabled for ${appName} during ${action}`);
} }
enableInstallButton(appName) { enableInstallButton(appName) {
@ -1538,7 +1529,6 @@ class AppsManager {
const spinners = button.querySelectorAll('.spinner'); const spinners = button.querySelectorAll('.spinner');
spinners.forEach(spinner => spinner.remove()); spinners.forEach(spinner => spinner.remove());
// console.log(`🔍 Install button enabled for ${appName}`);
} }
disableUninstallButton(appName, action) { disableUninstallButton(appName, action) {
@ -1579,7 +1569,6 @@ class AppsManager {
`; `;
} }
// console.log(`🔍 Uninstall button disabled for ${appName} during ${action}`);
} }
enableUninstallButton(appName) { enableUninstallButton(appName) {
@ -1604,7 +1593,6 @@ class AppsManager {
const spinners = button.querySelectorAll('.spinner'); const spinners = button.querySelectorAll('.spinner');
spinners.forEach(spinner => spinner.remove()); spinners.forEach(spinner => spinner.remove());
// console.log(`🔍 Uninstall button enabled for ${appName}`);
} }
// Static methods for global access // Static methods for global access
@ -1848,9 +1836,7 @@ class ServiceButtons {
// Get services for a specific app from config, then fill in real IPs/ports from apps-services.json // Get services for a specific app from config, then fill in real IPs/ports from apps-services.json
async getServicesForApp(appName) { async getServicesForApp(appName) {
const portConfig = this.parsePortConfig(appName); const portConfig = this.parsePortConfig(appName);
// console.log(`📦 Port config for ${appName}:`, portConfig);
const portServices = portConfig.filter(p => p.buttonEnabled); const portServices = portConfig.filter(p => p.buttonEnabled);
// console.log(`✅ Enabled services for ${appName}:`, portServices);
if (portServices.length === 0) return []; if (portServices.length === 0) return [];
@ -1858,7 +1844,6 @@ class ServiceButtons {
if (this.services.length === 0) { if (this.services.length === 0) {
await this.loadServices(); await this.loadServices();
} }
// console.log(`🌐 Loaded ${this.services.length} services from apps-services.json`);
// Merge port config with real data from apps-services.json // Merge port config with real data from apps-services.json
return portServices.map(portService => { return portServices.map(portService => {
@ -1868,7 +1853,6 @@ class ServiceButtons {
s.name === portService.name s.name === portService.name
); );
// console.log(`🔗 Matching service for ${portService.name}:`, serviceData);
const merged = { const merged = {
...portService, ...portService,
@ -1879,7 +1863,6 @@ class ServiceButtons {
externalURL: serviceData?.externalURL || '', externalURL: serviceData?.externalURL || '',
internalURL: serviceData?.internalURL || '' internalURL: serviceData?.internalURL || ''
}; };
// console.log(`🎯 Merged service data:`, merged);
return merged; return merged;
}); });
} }

View File

@ -77,22 +77,17 @@ class PortManager {
// Get available services for an app // Get available services for an app
async getAvailableServices(appName) { async getAvailableServices(appName) {
//console.log(`🔌 PortManager: Getting services for app: ${appName}`);
try { try {
// Load apps data to get services for this app (with cache busting) // Load apps data to get services for this app (with cache busting)
const timestamp = Date.now(); const timestamp = Date.now();
const response = await fetch(`/data/apps/generated/apps.json?t=${timestamp}`); const response = await fetch(`/data/apps/generated/apps.json?t=${timestamp}`);
if (!response.ok) { if (!response.ok) {
//console.log(`🔌 Failed to fetch apps.json: ${response.status}`);
return []; return [];
} }
const appsData = await response.json(); const appsData = await response.json();
//console.log(`🔌 Apps data loaded:`, appsData);
//console.log(`🔌 Available app names:`, appsData.apps.map(app => app.name));
let app = appsData.apps.find(a => a.name === appName); let app = appsData.apps.find(a => a.name === appName);
//console.log(`🔌 Found app for ${appName}:`, app);
// Try fuzzy matching if exact match fails // Try fuzzy matching if exact match fails
if (!app) { if (!app) {
@ -100,18 +95,15 @@ class PortManager {
a.name.toLowerCase().includes(appName.toLowerCase()) || a.name.toLowerCase().includes(appName.toLowerCase()) ||
appName.toLowerCase().includes(a.name.toLowerCase()) appName.toLowerCase().includes(a.name.toLowerCase())
); );
//console.log(`🔌 Fuzzy match for ${appName}:`, fuzzyApp);
if (fuzzyApp) { if (fuzzyApp) {
app = fuzzyApp; app = fuzzyApp;
} }
} }
if (app && app.services) { if (app && app.services) {
//console.log(`🔌 Services found for ${appName}:`, app.services);
return app.services; return app.services;
} }
//console.log(`🔌 No services found for ${appName}`);
return []; return [];
} catch (error) { } catch (error) {
console.error('Error loading services:', error); console.error('Error loading services:', error);
@ -196,7 +188,6 @@ class PortManager {
} }
} }
} catch (error) { } catch (error) {
//console.log('Could not fetch app title, using app name');
} }
// Show confirmation dialog // Show confirmation dialog
@ -477,8 +468,6 @@ class PortManager {
this.appName = appName; this.appName = appName;
this.availableServices = await this.getAvailableServices(appName); this.availableServices = await this.getAvailableServices(appName);
//console.log(`🔌 PortManager: Available services for ${appName}:`, this.availableServices);
//console.log(`🔌 PortManager: Number of services: ${this.availableServices.length}`);
// Force full-width layout for port manager containers // Force full-width layout for port manager containers
this.forceFullWidthLayout(); this.forceFullWidthLayout();
@ -489,7 +478,6 @@ class PortManager {
const index = parseInt(select.dataset.index); const index = parseInt(select.dataset.index);
const currentService = this.ports[index]?.service || ''; const currentService = this.ports[index]?.service || '';
//console.log(`🔌 PortManager: Port ${index} current service: "${currentService}"`);
// Clear existing options // Clear existing options
select.innerHTML = '<option value="">Select a service...</option>'; select.innerHTML = '<option value="">Select a service...</option>';
@ -508,22 +496,18 @@ class PortManager {
// Case 1: Only one service and no current service - auto-select // Case 1: Only one service and no current service - auto-select
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = true; isAutoMatched = true;
//console.log(`🔌 PortManager: Auto-selecting single service "${service}" for port ${index}`);
} else if (this.availableServices.length === 1 && currentService && currentService !== service) { } else if (this.availableServices.length === 1 && currentService && currentService !== service) {
// Case 2: Only one service but current service doesn't match - auto-match // Case 2: Only one service but current service doesn't match - auto-match
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = true; isAutoMatched = true;
//console.log(`🔌 PortManager: Auto-matching service "${service}" (was "${currentService}") for port ${index}`);
} else if (this.availableServices.length === 1 && currentService === service) { } else if (this.availableServices.length === 1 && currentService === service) {
// Case 3: Single service and current service matches - still show auto-match indicator // Case 3: Single service and current service matches - still show auto-match indicator
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = true; isAutoMatched = true;
//console.log(`🔌 PortManager: Single service matches "${service}" for port ${index} - showing auto-match indicator`);
} else if (this.availableServices.length > 1 && currentService === service) { } else if (this.availableServices.length > 1 && currentService === service) {
// Case 4: Multiple services and current service matches - normal selection // Case 4: Multiple services and current service matches - normal selection
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = false; isAutoMatched = false;
//console.log(`🔌 PortManager: Normal selection of service "${service}" for port ${index}`);
} }
if (shouldAutoSelect) { if (shouldAutoSelect) {
@ -732,7 +716,6 @@ class PortManager {
const index = parseInt(select.dataset.index); const index = parseInt(select.dataset.index);
const currentService = this.ports[index]?.service || ''; const currentService = this.ports[index]?.service || '';
//console.log(`🔌 PortManager: Port ${index} current service: "${currentService}"`);
// Clear existing options // Clear existing options
select.innerHTML = '<option value="">Select a service...</option>'; select.innerHTML = '<option value="">Select a service...</option>';
@ -751,22 +734,18 @@ class PortManager {
// Case 1: Only one service and no current service - auto-select // Case 1: Only one service and no current service - auto-select
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = true; isAutoMatched = true;
//console.log(`🔌 PortManager: Auto-selecting single service "${service}" for port ${index}`);
} else if (this.availableServices.length === 1 && currentService && currentService !== service) { } else if (this.availableServices.length === 1 && currentService && currentService !== service) {
// Case 2: Only one service but current service doesn't match - auto-match // Case 2: Only one service but current service doesn't match - auto-match
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = true; isAutoMatched = true;
//console.log(`🔌 PortManager: Auto-matching service "${service}" (was "${currentService}") for port ${index}`);
} else if (this.availableServices.length === 1 && currentService === service) { } else if (this.availableServices.length === 1 && currentService === service) {
// Case 3: Single service and current service matches - still show auto-match indicator // Case 3: Single service and current service matches - still show auto-match indicator
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = true; isAutoMatched = true;
//console.log(`🔌 PortManager: Single service matches "${service}" for port ${index} - showing auto-match indicator`);
} else if (this.availableServices.length > 1 && currentService === service) { } else if (this.availableServices.length > 1 && currentService === service) {
// Case 4: Multiple services and current service matches - normal selection // Case 4: Multiple services and current service matches - normal selection
shouldAutoSelect = true; shouldAutoSelect = true;
isAutoMatched = false; isAutoMatched = false;
//console.log(`🔌 PortManager: Normal selection of service "${service}" for port ${index}`);
} }
if (shouldAutoSelect) { if (shouldAutoSelect) {

View File

@ -114,15 +114,12 @@ function navigateToApp(appName) {
// Filter apps by search term (removed - not used in dashboard) // Filter apps by search term (removed - not used in dashboard)
function filterApps(searchTerm) { function filterApps(searchTerm) {
//console.log('Filter apps functionality removed from dashboard');
} }
// Filter apps by category (removed - not used in dashboard) // Filter apps by category (removed - not used in dashboard)
function filterAppsByCategory(category) { function filterAppsByCategory(category) {
//console.log('Filter apps by category functionality removed from dashboard');
} }
// Populate category filter (removed - not used in dashboard) // Populate category filter (removed - not used in dashboard)
function populateCategoryFilter() { function populateCategoryFilter() {
//console.log('Category filter population removed from dashboard');
} }

View File

@ -55,7 +55,6 @@ Object.assign(TasksManager.prototype, {
} }
// Get tasks using new system // Get tasks using new system
// console.log('📥 Getting tasks using new queue system...');
// Get queue and current status // Get queue and current status
let queue = []; let queue = [];
@ -75,7 +74,6 @@ Object.assign(TasksManager.prototype, {
} }
} }
} catch (error) { } catch (error) {
// console.log('📝 Queue file not found, starting with empty queue');
} }
try { try {
@ -92,7 +90,6 @@ Object.assign(TasksManager.prototype, {
} }
} }
} catch (error) { } catch (error) {
// console.log('📝 Current file not found, no current task');
} }
// Load individual task files // Load individual task files
@ -120,7 +117,6 @@ Object.assign(TasksManager.prototype, {
// Scan tasks folder for all task files (including completed ones) - OPTIMIZED // Scan tasks folder for all task files (including completed ones) - OPTIMIZED
try { try {
// console.log('🔍 Scanning tasks folder for all task files...');
const tasksResponse = await fetch('/read-directory?path=tasks'); const tasksResponse = await fetch('/read-directory?path=tasks');
if (tasksResponse.ok) { if (tasksResponse.ok) {
const files = await tasksResponse.json(); const files = await tasksResponse.json();
@ -130,7 +126,6 @@ Object.assign(TasksManager.prototype, {
file !== 'current.json' file !== 'current.json'
); );
// console.log(`📁 Found ${taskFiles.length} task files in folder`);
// OPTIMIZATION: Batch load tasks instead of individual calls // OPTIMIZATION: Batch load tasks instead of individual calls
const missingTaskIds = taskFiles const missingTaskIds = taskFiles
@ -138,7 +133,6 @@ Object.assign(TasksManager.prototype, {
.filter(taskId => !allTasks.find(task => task.id === taskId)); .filter(taskId => !allTasks.find(task => task.id === taskId));
if (missingTaskIds.length > 0) { if (missingTaskIds.length > 0) {
// console.log(`📦 Batch loading ${missingTaskIds.length} missing tasks...`);
try { try {
const batchResponse = await fetch('/read-tasks-batch', { const batchResponse = await fetch('/read-tasks-batch', {
method: 'POST', method: 'POST',
@ -151,12 +145,10 @@ Object.assign(TasksManager.prototype, {
batchTasks.forEach(task => { batchTasks.forEach(task => {
if (task) { if (task) {
allTasks.push(task); allTasks.push(task);
// console.log(`✅ Added completed task ${task.id} from batch load`);
} }
}); });
} else { } else {
// Fallback to individual loading if batch endpoint not available // Fallback to individual loading if batch endpoint not available
// console.log('⚠️ Batch endpoint not available, falling back to individual loading');
await this.loadTasksIndividually(missingTaskIds, allTasks); await this.loadTasksIndividually(missingTaskIds, allTasks);
} }
} catch (error) { } catch (error) {
@ -181,7 +173,6 @@ Object.assign(TasksManager.prototype, {
// Sort by creation time (newest first) // Sort by creation time (newest first)
this.tasks.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)); this.tasks.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
// console.log(`✅ Loaded ${this.tasks.length} tasks`);
//// // console.log('📋 All tasks:', this.tasks); //// // console.log('📋 All tasks:', this.tasks);
this.renderTasks(); this.renderTasks();
@ -207,7 +198,6 @@ Object.assign(TasksManager.prototype, {
const task = await this.taskManager.getTask(taskId); const task = await this.taskManager.getTask(taskId);
if (task) { if (task) {
allTasks.push(task); allTasks.push(task);
// console.log(`✅ Added completed task ${taskId} from individual load`);
} }
} catch (error) { } catch (error) {
console.warn(`⚠️ Failed to load task ${taskId}:`, error); console.warn(`⚠️ Failed to load task ${taskId}:`, error);

View File

@ -149,7 +149,6 @@ Object.assign(TasksManager.prototype, {
return displayNames[category] || category.charAt(0).toUpperCase() + category.slice(1); return displayNames[category] || category.charAt(0).toUpperCase() + category.slice(1);
}, },
renderTask(task) { renderTask(task) {
// console.log(`🔍 renderTask called with task:`, task);
// Debug undefined status // Debug undefined status
if (!task.status) { if (!task.status) {
@ -164,24 +163,10 @@ Object.assign(TasksManager.prototype, {
const hasError = task.error && task.error.length > 0; const hasError = task.error && task.error.length > 0;
const hasLogs = task.log && Array.isArray(task.log) && task.log.length > 0; const hasLogs = task.log && Array.isArray(task.log) && task.log.length > 0;
// console.log(`🔍 Task fields check:`, {
//hasOutput: hasOutput,
//hasError: hasError,
//hasLogs: hasLogs,
//isRunning: isRunning,
//outputLength: task.output ? task.output.length : 0,
//error: task.error,
//logCount: task.log ? task.log.length : 0
//});
const executionTime = task.startedAt && task.completedAt ? const executionTime = task.startedAt && task.completedAt ?
this.calculateExecutionTime(task.startedAt, task.completedAt) : null; this.calculateExecutionTime(task.startedAt, task.completedAt) : null;
// console.log('🔍 renderTask debug:', {
//taskStatus: task.status,
//statusClass: statusClass,
//statusDisplay: task.status ? task.status.toUpperCase() : 'UNKNOWN'
//});
return ` return `
<div class="task-item" data-task-id="${task.id}"> <div class="task-item" data-task-id="${task.id}">
@ -390,7 +375,6 @@ Object.assign(TasksManager.prototype, {
} }
} }
} catch (error) { } catch (error) {
// console.log('Could not load apps.json, will use fallback');
} }
} }
@ -413,7 +397,6 @@ Object.assign(TasksManager.prototype, {
// If no installed apps found from apps data, fall back to task-based apps // If no installed apps found from apps data, fall back to task-based apps
if (installedApps.length === 0) { if (installedApps.length === 0) {
// console.log('No installed apps found, using task-based app list');
const taskApps = [...new Set(this.tasks.map(task => task.app).filter(Boolean))]; const taskApps = [...new Set(this.tasks.map(task => task.app).filter(Boolean))];
if (taskApps.length === 0) { if (taskApps.length === 0) {

View File

@ -92,7 +92,6 @@ Object.assign(TasksManager.prototype, {
const streamData = this.activeLogStreams.get(taskId); const streamData = this.activeLogStreams.get(taskId);
streamData.stream.stop(); streamData.stream.stop();
this.activeLogStreams.delete(taskId); this.activeLogStreams.delete(taskId);
// console.log(`⏹️ Stopped log streaming for task ${taskId}`);
} }
}, },
// Load task logs automatically // Load task logs automatically
@ -201,26 +200,20 @@ Object.assign(TasksManager.prototype, {
}, },
// Start global live log updater - simple 2-second updates for all running tasks // Start global live log updater - simple 2-second updates for all running tasks
startGlobalLiveLogUpdater() { startGlobalLiveLogUpdater() {
// console.log(`🔄 Starting global live log updater`);
// Update every 2 seconds // Update every 2 seconds
setInterval(async () => { setInterval(async () => {
// console.log(`🔄 Global updater running - checking tasks...`);
// Find all running tasks // Find all running tasks
const runningTasks = this.tasks.filter(task => task.status === 'running'); const runningTasks = this.tasks.filter(task => task.status === 'running');
// console.log(`🔄 Found ${runningTasks.length} running tasks:`, runningTasks.map(t => t.id));
if (runningTasks.length > 0) { if (runningTasks.length > 0) {
// console.log(`🔄 Updating live logs for ${runningTasks.length} running tasks`);
// Update each running task's live logs // Update each running task's live logs
for (const task of runningTasks) { for (const task of runningTasks) {
// console.log(`🔄 About to update live logs for task ${task.id}`);
await this.updateLiveLogsSimple(task.id); await this.updateLiveLogsSimple(task.id);
} }
} else { } else {
// console.log(`🔄 No running tasks found, skipping live log updates`);
} }
}, 2000); // Every 2 seconds }, 2000); // Every 2 seconds
}, },
@ -228,26 +221,20 @@ Object.assign(TasksManager.prototype, {
async updateLiveLogsSimple(taskId) { async updateLiveLogsSimple(taskId) {
const liveLogsElement = document.getElementById(`live-logs-${taskId}`); const liveLogsElement = document.getElementById(`live-logs-${taskId}`);
if (!liveLogsElement) { if (!liveLogsElement) {
// console.log(`⚠️ Live logs element not found for task ${taskId}`);
return; // Silently skip if element not found return; // Silently skip if element not found
} }
try { try {
// console.log(`🔄 Reading log file for task ${taskId}`);
// Read the log file content // Read the log file content
const response = await fetch(`/read-file?path=tasks/${taskId}.log`); const response = await fetch(`/read-file?path=tasks/${taskId}.log`);
// console.log(`🔄 Log file response status: ${response.status} for task ${taskId}`);
if (response.ok) { if (response.ok) {
const logContent = await response.text(); const logContent = await response.text();
// console.log(`🔄 Log file content length: ${logContent.length} chars for task ${taskId}`);
// console.log(`🔄 First 100 chars of log content: "${logContent.substring(0, 100)}..."`);
if (logContent.trim()) { if (logContent.trim()) {
// Split into lines and display // Split into lines and display
const lines = logContent.split('\n').filter(line => line.trim()); const lines = logContent.split('\n').filter(line => line.trim());
// console.log(`🔄 Displaying ${lines.length} log lines for task ${taskId}`);
liveLogsElement.innerHTML = lines.map(line => liveLogsElement.innerHTML = lines.map(line =>
`<div class="log-entry">${this.parseAnsiColors(line)}</div>` `<div class="log-entry">${this.parseAnsiColors(line)}</div>`
@ -255,7 +242,6 @@ Object.assign(TasksManager.prototype, {
// Auto-scroll to bottom // Auto-scroll to bottom
liveLogsElement.scrollTop = liveLogsElement.scrollHeight; liveLogsElement.scrollTop = liveLogsElement.scrollHeight;
} else { } else {
// console.log(`🔄 Log file is empty for task ${taskId}`);
liveLogsElement.innerHTML = '<div class="log-entry">🔄 Waiting for logs...</div>'; liveLogsElement.innerHTML = '<div class="log-entry">🔄 Waiting for logs...</div>';
} }
} else { } else {
@ -276,12 +262,10 @@ Object.assign(TasksManager.prototype, {
const detailsElement = taskElement.querySelector('.task-details'); const detailsElement = taskElement.querySelector('.task-details');
if (!detailsElement) return; if (!detailsElement) return;
// console.log(`🔄 Updating task structure for ${taskId} to show simplified logs`);
// Check if logs container already exists // Check if logs container already exists
const existingLogs = detailsElement.querySelector('.task-logs .log-container'); const existingLogs = detailsElement.querySelector('.task-logs .log-container');
if (existingLogs) { if (existingLogs) {
// console.log(`🔄 Logs container already exists for ${taskId}`);
return; // Already exists, no need to update return; // Already exists, no need to update
} }
@ -297,7 +281,6 @@ Object.assign(TasksManager.prototype, {
// Insert logs section at the bottom of details // Insert logs section at the bottom of details
detailsElement.insertAdjacentHTML('beforeend', logsHtml); detailsElement.insertAdjacentHTML('beforeend', logsHtml);
// console.log(`✅ Added simplified logs section for task ${taskId}`);
// Auto-load logs // Auto-load logs
this.loadTaskLogs(taskId); this.loadTaskLogs(taskId);
@ -312,7 +295,6 @@ Object.assign(TasksManager.prototype, {
return; return;
} }
// console.log(`🔄 Found task element:`, taskElement);
// Update status and content // Update status and content
const statusElement = taskElement.querySelector('.task-status'); const statusElement = taskElement.querySelector('.task-status');
@ -338,7 +320,6 @@ Object.assign(TasksManager.prototype, {
contentElement.textContent = task.command; contentElement.textContent = task.command;
} }
// console.log(`🔄 Updated task ${task.id} display: ${task.status}`);
}, },
// Update highlighted task status and UI // Update highlighted task status and UI
async updateHighlightedTaskStatus(taskId) { async updateHighlightedTaskStatus(taskId) {
@ -347,14 +328,12 @@ Object.assign(TasksManager.prototype, {
const task = await this.taskManager.getTaskSummary(taskId); const task = await this.taskManager.getTaskSummary(taskId);
if (!task) return; if (!task) return;
// console.log(`🔄 Updating highlighted task ${taskId} status: ${task.status}`);
// Update task display // Update task display
this.updateTaskDisplay(task); this.updateTaskDisplay(task);
// If task completed or failed, always load output // If task completed or failed, always load output
if ((task.status === 'completed' || task.status === 'failed')) { if ((task.status === 'completed' || task.status === 'failed')) {
// console.log(`🔄 Task ${taskId} is ${task.status}, loading output...`);
const details = document.getElementById(`details-${taskId}`); const details = document.getElementById(`details-${taskId}`);
if (details && details.style.display === 'block') { if (details && details.style.display === 'block') {

View File

@ -145,12 +145,10 @@ class TasksManager {
// Only check for specific task parameter if we're not coming from an app page // Only check for specific task parameter if we're not coming from an app page
const taskParam = searchParams.get('task'); const taskParam = searchParams.get('task');
if (taskParam) { if (taskParam) {
// console.log(`🎯 Found task parameter in URL: ${taskParam} on main tasks page`);
this.highlightedTaskId = taskParam; this.highlightedTaskId = taskParam;
} else { } else {
// Clear any existing highlighted task when on main tasks page without task param // Clear any existing highlighted task when on main tasks page without task param
this.highlightedTaskId = null; this.highlightedTaskId = null;
// console.log(`🎯 Clearing highlighted task on main tasks page`);
} }
} else { } else {
// Not on main tasks page, get default filter from localStorage // Not on main tasks page, get default filter from localStorage
@ -158,7 +156,6 @@ class TasksManager {
this.highlightedTaskId = null; // Always clear when not on tasks page this.highlightedTaskId = null; // Always clear when not on tasks page
} }
// console.log(`🎯 Tasks category from URL: ${this.currentCategory}`);
} }
updateURL(category, taskId = null) { updateURL(category, taskId = null) {
@ -186,7 +183,6 @@ class TasksManager {
await this.loadTasks(); await this.loadTasks();
// Force a refresh to ensure latest data // Force a refresh to ensure latest data
// console.log('🔄 Refreshing tasks data on initialization...');
await this.loadTasks(); await this.loadTasks();
// Setup auto-refresh // Setup auto-refresh

View File

@ -99,7 +99,6 @@ Object.assign(TasksManager.prototype, {
}, },
// Auto-expand a task when it's created // Auto-expand a task when it's created
async autoExpandTask(taskId) { async autoExpandTask(taskId) {
// console.log(`🔄 Auto-expanding task ${taskId}`);
// Wait for task to be rendered // Wait for task to be rendered
let attempts = 0; let attempts = 0;
@ -107,12 +106,10 @@ Object.assign(TasksManager.prototype, {
const tryExpand = async () => { const tryExpand = async () => {
attempts++; attempts++;
// console.log(`🔄 Auto-expand attempt ${attempts}/${maxAttempts} for task ${taskId}`);
// Check if task element exists // Check if task element exists
const taskElement = document.querySelector(`[data-task-id="${taskId}"]`); const taskElement = document.querySelector(`[data-task-id="${taskId}"]`);
if (!taskElement) { if (!taskElement) {
// console.log(`⚠️ Task element not found for ${taskId}, attempt ${attempts}`);
if (attempts < maxAttempts) { if (attempts < maxAttempts) {
setTimeout(tryExpand, 500); // Try again in 500ms setTimeout(tryExpand, 500); // Try again in 500ms
} else { } else {
@ -121,12 +118,10 @@ Object.assign(TasksManager.prototype, {
return; return;
} }
// console.log(`✅ Found task element for ${taskId}`);
// Get the details element // Get the details element
const details = document.getElementById(`details-${taskId}`); const details = document.getElementById(`details-${taskId}`);
if (!details) { if (!details) {
// console.log(`⚠️ Details element not found for ${taskId}, attempt ${attempts}`);
if (attempts < maxAttempts) { if (attempts < maxAttempts) {
setTimeout(tryExpand, 500); setTimeout(tryExpand, 500);
} else { } else {
@ -135,7 +130,6 @@ Object.assign(TasksManager.prototype, {
return; return;
} }
// console.log(`✅ Found details element for ${taskId}`);
// Expand the task details // Expand the task details
details.style.display = 'block'; details.style.display = 'block';
@ -158,7 +152,6 @@ Object.assign(TasksManager.prototype, {
}, 1000); }, 1000);
} }
// console.log(`✅ Auto-expanded task ${taskId}`);
}; };
tryExpand(); tryExpand();

View File

@ -18,9 +18,7 @@ class SystemLoader {
this.initializeSystems(); this.initializeSystems();
this.initializeHealthChecks(); this.initializeHealthChecks();
// console.log('🚨 BREAKPOINT: About to call initializeComponents()');
this.initializeComponentRegistry(); this.initializeComponentRegistry();
// console.log('BREAKPOINT: initializeComponents() completed');
} }
// Initialize component registry // Initialize component registry
@ -60,7 +58,6 @@ class SystemLoader {
initializer: () => { initializer: () => {
if (typeof setupMobileMenu === 'function') { if (typeof setupMobileMenu === 'function') {
setupMobileMenu(); setupMobileMenu();
// console.log('✅ Mobile menu initialized');
return true; return true;
} }
console.warn('⚠️ setupMobileMenu not available'); console.warn('⚠️ setupMobileMenu not available');
@ -81,7 +78,6 @@ class SystemLoader {
initializer: () => { initializer: () => {
if (typeof initConfirmationDialog === 'function') { if (typeof initConfirmationDialog === 'function') {
initConfirmationDialog(); initConfirmationDialog();
// console.log('✅ Confirmation dialog initialized');
return true; return true;
} }
console.warn('⚠️ initConfirmationDialog not available'); console.warn('⚠️ initConfirmationDialog not available');
@ -98,7 +94,6 @@ class SystemLoader {
initializer: () => { initializer: () => {
if (typeof NotificationSystem !== 'undefined') { if (typeof NotificationSystem !== 'undefined') {
window.notificationSystem = new NotificationSystem(); window.notificationSystem = new NotificationSystem();
// console.log('✅ Notification system initialized');
return window.notificationSystem; return window.notificationSystem;
} }
console.warn('⚠️ NotificationSystem not available'); console.warn('⚠️ NotificationSystem not available');
@ -116,18 +111,15 @@ class SystemLoader {
// Initialize data loading system // Initialize data loading system
if (typeof initializeData === 'function') { if (typeof initializeData === 'function') {
initializeData(); initializeData();
// console.log('✅ Data loading system initialized');
} }
// Initialize dashboard-specific functions // Initialize dashboard-specific functions
if (typeof loadSystemInfo === 'function') { if (typeof loadSystemInfo === 'function') {
loadSystemInfo(); loadSystemInfo();
// console.log('✅ System info loaded');
} }
if (typeof setupEventListeners === 'function') { if (typeof setupEventListeners === 'function') {
setupEventListeners(); setupEventListeners();
// console.log('✅ Dashboard event listeners set up');
} }
return true; return true;
@ -141,7 +133,6 @@ class SystemLoader {
this.components.set('task-system', { this.components.set('task-system', {
system: 'task', system: 'task',
initializer: () => { initializer: () => {
// console.log('🔧 Initializing Task System...');
// Open the SSE feed before anything else so we don't miss the upserts // Open the SSE feed before anything else so we don't miss the upserts
// that fire as the page boots. // that fire as the page boots.
@ -152,7 +143,6 @@ class SystemLoader {
// Create TasksManager instance // Create TasksManager instance
if (typeof TasksManager !== 'undefined') { if (typeof TasksManager !== 'undefined') {
window.tasksManager = new TasksManager(); window.tasksManager = new TasksManager();
// console.log('✅ TasksManager initialized and available globally');
return window.tasksManager; return window.tasksManager;
} }
@ -185,15 +175,10 @@ class SystemLoader {
this.components.set('apps-manager', { this.components.set('apps-manager', {
system: 'managers', system: 'managers',
initializer: () => { initializer: () => {
// console.log('🔧 DEBUG: AppsManager initializer called');
// console.log('🔧 DEBUG: AppsManager class available:', typeof AppsManager !== 'undefined');
// console.log('🔧 DEBUG: Available globals:', Object.keys(window).filter(key => key.includes('Manager')));
if (typeof AppsManager !== 'undefined') { if (typeof AppsManager !== 'undefined') {
// console.log('🔧 DEBUG: Creating AppsManager instance...');
try { try {
window.appsManager = new AppsManager(); window.appsManager = new AppsManager();
// console.log('✅ AppsManager instance created successfully');
return window.appsManager; return window.appsManager;
} catch (error) { } catch (error) {
console.error('❌ Failed to create AppsManager instance:', error); console.error('❌ Failed to create AppsManager instance:', error);
@ -229,13 +214,9 @@ class SystemLoader {
this.components.set('app-tabbed-manager', { this.components.set('app-tabbed-manager', {
system: 'managers', system: 'managers',
initializer: () => { initializer: () => {
// console.log('🔧 DEBUG: Attempting to initialize AppTabbedManager...');
// console.log('🔧 DEBUG: AppTabbedManager class available:', typeof AppTabbedManager !== 'undefined');
// console.log('🔧 DEBUG: Available globals:', Object.keys(window).filter(key => key.includes('Tabbed') || key.includes('Manager')));
if (typeof AppTabbedManager !== 'undefined') { if (typeof AppTabbedManager !== 'undefined') {
window.appTabbedManager = new AppTabbedManager(); window.appTabbedManager = new AppTabbedManager();
// console.log('✅ App Tabbed Manager initialized');
return window.appTabbedManager; return window.appTabbedManager;
} }
console.warn('⚠️ AppTabbedManager not available'); console.warn('⚠️ AppTabbedManager not available');
@ -246,8 +227,6 @@ class SystemLoader {
script: '/components/apps/core/js/app-tabbed-manager.js' script: '/components/apps/core/js/app-tabbed-manager.js'
}); });
// console.log('TEST: Components added. Total components:', this.components.size);
// console.log('TEST: Method completed');
} }
// Initialize all system definitions // Initialize all system definitions
@ -259,7 +238,6 @@ class SystemLoader {
dependencies: [], dependencies: [],
checks: ['dom', 'spa', 'utils'] checks: ['dom', 'spa', 'utils']
}); });
// console.log('🔍 Core System checks:', ['dom', 'spa', 'utils']);
this.systems.set('data', { this.systems.set('data', {
name: 'Data Functions', name: 'Data Functions',
@ -268,7 +246,6 @@ class SystemLoader {
dependencies: ['core'], dependencies: ['core'],
checks: [] checks: []
}); });
// console.log('🔍 Data Functions checks:', []);
this.systems.set('components', { this.systems.set('components', {
name: 'UI Components', name: 'UI Components',
@ -369,16 +346,6 @@ class SystemLoader {
const hasDataLoader = typeof DataLoader !== 'undefined'; const hasDataLoader = typeof DataLoader !== 'undefined';
const hasInitializeData = typeof initializeData === 'function'; const hasInitializeData = typeof initializeData === 'function';
// console.log('🔍 Utils Check:', {
//hasDataLoader,
//hasSafeGetElement,
//hasSafeQuerySelector,
//hasGetAppIcon,
//hasSetupThemeToggle,
//hasInitializeData,
// Check what's actually available globally
//availableGlobals: Object.keys(window).filter(key =>
//key.includes('safe') ||
//key.includes('get') || //key.includes('get') ||
//key.includes('Data') || //key.includes('Data') ||
//key.includes('Theme') || //key.includes('Theme') ||
@ -410,19 +377,6 @@ class SystemLoader {
const hasLoadConfigDetailData = typeof loadConfigDetailData === 'function'; const hasLoadConfigDetailData = typeof loadConfigDetailData === 'function';
const hasLoadMinimalData = typeof loadMinimalData === 'function'; const hasLoadMinimalData = typeof loadMinimalData === 'function';
// console.log('🔍 Data Loader Check:', {
//hasDataLoader,
//hasInitializeData,
//hasLoadDashboardData,
//hasLoadAppsPageData,
//hasLoadConfigDetailData,
//hasLoadMinimalData,
//availableDataFunctions: Object.keys(window).filter(key =>
//key.includes('load') ||
//key.includes('Data') ||
//key.includes('initialize')
//).slice(0, 10)
//});
// Check if data loader functions are available // Check if data loader functions are available
return hasInitializeData && (hasLoadDashboardData || hasLoadAppsPageData || hasLoadConfigDetailData); return hasInitializeData && (hasLoadDashboardData || hasLoadAppsPageData || hasLoadConfigDetailData);
@ -439,7 +393,6 @@ class SystemLoader {
weight: 2, weight: 2,
timeout: 1000, // Reduced timeout since we're not actually checking timeout: 1000, // Reduced timeout since we're not actually checking
check: async () => { check: async () => {
// console.log('🔍 Topbar Check: Will be loaded dynamically during component initialization');
// Always pass - TopbarComponent will be loaded dynamically by mobile-menu component // Always pass - TopbarComponent will be loaded dynamically by mobile-menu component
return true; return true;
} }
@ -452,7 +405,6 @@ class SystemLoader {
weight: 1, weight: 1,
timeout: 1000, timeout: 1000,
check: async () => { check: async () => {
// console.log('🔍 Confirmation Dialog Check: Will be loaded dynamically during component initialization');
return true; return true;
} }
}); });
@ -463,7 +415,6 @@ class SystemLoader {
weight: 1, weight: 1,
timeout: 1000, // Reduced timeout since we're not actually checking timeout: 1000, // Reduced timeout since we're not actually checking
check: async () => { check: async () => {
// console.log('🔍 Notification System Check: Will be loaded dynamically during component initialization');
// Always pass - NotificationSystem will be loaded dynamically by notifications component // Always pass - NotificationSystem will be loaded dynamically by notifications component
return true; return true;
} }
@ -484,7 +435,6 @@ class SystemLoader {
weight: 3, weight: 3,
timeout: 1000, // Reduced timeout since we're not actually checking timeout: 1000, // Reduced timeout since we're not actually checking
check: async () => { check: async () => {
// console.log('🔍 Apps Manager Check: Will be loaded dynamically during component initialization');
// Always pass - AppsManager will be loaded dynamically by apps-manager component // Always pass - AppsManager will be loaded dynamically by apps-manager component
return true; return true;
} }
@ -496,7 +446,6 @@ class SystemLoader {
weight: 3, weight: 3,
timeout: 1000, // Reduced timeout since we're not actually checking timeout: 1000, // Reduced timeout since we're not actually checking
check: async () => { check: async () => {
// console.log('🔍 Task Manager Check: Will be loaded dynamically during component initialization');
// Always pass - TasksManager will be loaded dynamically by task-manager component // Always pass - TasksManager will be loaded dynamically by task-manager component
return true; return true;
} }
@ -508,7 +457,6 @@ class SystemLoader {
weight: 2, weight: 2,
timeout: 1000, // Reduced timeout since we're not actually checking timeout: 1000, // Reduced timeout since we're not actually checking
check: async () => { check: async () => {
// console.log('🔍 Config Manager Check: Will be loaded dynamically during component initialization');
// Always pass - ConfigManager will be loaded dynamically by config-manager component // Always pass - ConfigManager will be loaded dynamically by config-manager component
return true; return true;
} }
@ -520,7 +468,6 @@ class SystemLoader {
weight: 3, weight: 3,
timeout: 1000, // Reduced timeout since we're not actually checking timeout: 1000, // Reduced timeout since we're not actually checking
check: async () => { check: async () => {
// console.log('🔍 App Tabbed Manager Check: Will be loaded dynamically during component initialization');
// Always pass - AppTabbedManager will be loaded dynamically by app-tabbed-manager component // Always pass - AppTabbedManager will be loaded dynamically by app-tabbed-manager component
return true; return true;
} }
@ -598,38 +545,30 @@ class SystemLoader {
// Icon Preloading Check // Icon Preloading Check
async checkIconPreloading() { async checkIconPreloading() {
// console.log('🔄 Starting icon preloading check...');
// Load data directly since window.apps isn't populated yet // Load data directly since window.apps isn't populated yet
let appsData = []; let appsData = [];
let categoriesData = []; let categoriesData = [];
try { try {
// console.log('🌐 Fetching data from /data/apps/generated/apps.json and /data/apps/apps-categories.json');
const [appsResponse, categoriesResponse] = await Promise.all([ const [appsResponse, categoriesResponse] = await Promise.all([
fetch('/data/apps/generated/apps.json'), fetch('/data/apps/generated/apps.json'),
fetch('/data/apps/apps-categories.json') fetch('/data/apps/apps-categories.json')
]); ]);
// console.log('📊 Apps response status:', appsResponse.status, appsResponse.statusText);
// console.log('📊 Categories response status:', categoriesResponse.status, categoriesResponse.statusText);
if (appsResponse.ok) { if (appsResponse.ok) {
const appsText = await appsResponse.text(); const appsText = await appsResponse.text();
// console.log('📄 Apps response text length:', appsText.length);
const appsParsed = JSON.parse(appsText); const appsParsed = JSON.parse(appsText);
appsData = appsParsed.apps || []; appsData = appsParsed.apps || [];
// console.log('✅ Apps data loaded successfully');
} else { } else {
console.warn('⚠️ Apps response not ok:', appsResponse.status); console.warn('⚠️ Apps response not ok:', appsResponse.status);
} }
if (categoriesResponse.ok) { if (categoriesResponse.ok) {
const categoriesText = await categoriesResponse.text(); const categoriesText = await categoriesResponse.text();
// console.log('📄 Categories response text length:', categoriesText.length);
const categoriesParsed = JSON.parse(categoriesText); const categoriesParsed = JSON.parse(categoriesText);
categoriesData = categoriesParsed.categories || []; categoriesData = categoriesParsed.categories || [];
// console.log('✅ Categories data loaded successfully');
} else { } else {
console.warn('⚠️ Categories response not ok:', categoriesResponse.status); console.warn('⚠️ Categories response not ok:', categoriesResponse.status);
} }
@ -637,8 +576,6 @@ class SystemLoader {
console.warn('⚠️ Failed to load data for icon preloading:', error); console.warn('⚠️ Failed to load data for icon preloading:', error);
} }
// console.log('📊 Apps data length:', appsData?.length || 0);
// console.log('📊 Categories data length:', categoriesData?.length || 0);
// Collect all icon URLs to preload // Collect all icon URLs to preload
const iconUrls = new Set(); const iconUrls = new Set();
@ -669,7 +606,6 @@ class SystemLoader {
iconUrls.add('/core/icons/categories/all.svg'); iconUrls.add('/core/icons/categories/all.svg');
iconUrls.add('/core/icons/categories/installed.svg'); iconUrls.add('/core/icons/categories/installed.svg');
// console.log(`📦 Found ${iconUrls.size} unique icons to preload`);
// Preload all icons using Image objects // Preload all icons using Image objects
const preloadPromises = Array.from(iconUrls).map(iconUrl => { const preloadPromises = Array.from(iconUrls).map(iconUrl => {
@ -682,14 +618,11 @@ class SystemLoader {
}); });
await Promise.all(preloadPromises); await Promise.all(preloadPromises);
// console.log(`✅ Preloaded ${iconUrls.size} app center icons`);
// Pre-render app center in background // Pre-render app center in background
if (window.appsManager && typeof window.appsManager.showAppsList === 'function') { if (window.appsManager && typeof window.appsManager.showAppsList === 'function') {
// console.log('🔄 Pre-rendering app center content...');
window.appsManager.showAppsList('all'); window.appsManager.showAppsList('all');
await new Promise(resolve => setTimeout(resolve, 300)); // Wait for rendering await new Promise(resolve => setTimeout(resolve, 300)); // Wait for rendering
// console.log('✅ App center pre-rendered');
} }
return true; return true;
@ -725,15 +658,12 @@ class SystemLoader {
// Initialize all components in dependency order // Initialize all components in dependency order
async initializeComponents() { async initializeComponents() {
// console.log('🔧 BREAKPOINT: initializeComponents() called!');
// console.log('🔧 Initializing components...');
// Get systems in priority order // Get systems in priority order
const sortedSystems = Array.from(this.systems.entries()) const sortedSystems = Array.from(this.systems.entries())
.sort(([,a], [,b]) => a.priority - b.priority); .sort(([,a], [,b]) => a.priority - b.priority);
for (const [systemId, system] of sortedSystems) { for (const [systemId, system] of sortedSystems) {
// console.log(`🔄 Processing system: ${systemId}`);
// Check dependencies first // Check dependencies first
const dependenciesMet = system.dependencies.every(dep => const dependenciesMet = system.dependencies.every(dep =>
@ -741,7 +671,6 @@ class SystemLoader {
); );
if (!dependenciesMet) { if (!dependenciesMet) {
// console.log(`⏳ Skipping ${system.name} - dependencies not met:`, system.dependencies);
continue; continue;
} }
@ -749,19 +678,15 @@ class SystemLoader {
const systemComponents = Array.from(this.components.entries()) const systemComponents = Array.from(this.components.entries())
.filter(([, component]) => component.system === systemId); .filter(([, component]) => component.system === systemId);
// console.log(`📦 Found ${systemComponents.length} components for ${systemId}:`, systemComponents.map(([id]) => id));
// Initialize components for this system // Initialize components for this system
for (const [componentId, component] of systemComponents) { for (const [componentId, component] of systemComponents) {
try { try {
// console.log(`🔧 Initializing ${componentId}...`);
// Load component script(s) if specified // Load component script(s) if specified
if (component.script) { if (component.script) {
// console.log(`📦 Loading script for ${componentId}: ${component.script}`);
await this.loadScript(component.script); await this.loadScript(component.script);
} else if (component.scripts) { } else if (component.scripts) {
// console.log(`📦 Loading scripts for ${componentId}:`, component.scripts);
await this.loadScripts(component.scripts); await this.loadScripts(component.scripts);
} }
@ -771,7 +696,6 @@ class SystemLoader {
); );
if (!componentDepsMet) { if (!componentDepsMet) {
// console.log(`⏳ Skipping ${componentId} - component dependencies not met:`, component.dependencies);
continue; continue;
} }
@ -781,10 +705,8 @@ class SystemLoader {
// Store result if available // Store result if available
if (result && component.global) { if (result && component.global) {
window[component.global] = result; window[component.global] = result;
// console.log(`✅ ${componentId} stored as global: ${component.global}`);
} }
// console.log(`✅ ${componentId} initialized successfully`);
} catch (error) { } catch (error) {
console.error(`❌ Failed to initialize ${componentId}:`, error); console.error(`❌ Failed to initialize ${componentId}:`, error);
@ -798,10 +720,8 @@ class SystemLoader {
// Mark system as initialized // Mark system as initialized
system.initialized = true; system.initialized = true;
// console.log(`✅ ${system.name} system initialized`);
} }
// console.log('🎉 Component initialization complete');
} }
// Load a script dynamically // Load a script dynamically
@ -839,8 +759,6 @@ class SystemLoader {
results.get(dep)?.status === 'passed' results.get(dep)?.status === 'passed'
); );
// console.log(`🔍 Processing system: ${system.name} (priority: ${system.priority}, critical: ${system.critical})`);
// console.log(`🔍 Dependencies met: ${dependenciesMet}`);
if (!dependenciesMet) { if (!dependenciesMet) {
results.set(systemId, { results.set(systemId, {
@ -856,7 +774,6 @@ class SystemLoader {
// If system has no checks, it automatically passes // If system has no checks, it automatically passes
if (system.checks.length === 0) { if (system.checks.length === 0) {
// console.log(`✅ System "${system.name}" (${systemId}) has no checks - automatically passing`);
// Trigger status update for systems with no checks // Trigger status update for systems with no checks
this.trigger('onSystemCheck', { this.trigger('onSystemCheck', {
@ -880,15 +797,12 @@ class SystemLoader {
status: 'checking' status: 'checking'
}); });
// console.log(`🔍 System "${system.name}" (${systemId}) is running check "${check.name}" (${checkId})`);
try { try {
const result = await this.runSingleCheck(checkId, check); const result = await this.runSingleCheck(checkId, check);
systemResults.push(result); systemResults.push(result);
if (result.status === 'failed') { if (result.status === 'failed') {
// console.log(`❌ Check failed: ${check.name} for system ${system.name}`);
// console.log(`🔍 System critical: ${system.critical}`);
this.errors.push({ this.errors.push({
system: system.name, system: system.name,
@ -921,8 +835,6 @@ class SystemLoader {
} }
} }
} catch (error) { } catch (error) {
// console.log(`❌ Exception in check: ${check.name} for system ${system.name}:`, error.message);
// console.log(`🔍 System critical: ${system.critical}`);
systemResults.push({ systemResults.push({
id: checkId, id: checkId,
@ -989,7 +901,6 @@ class SystemLoader {
const startTime = Date.now(); const startTime = Date.now();
try { try {
// console.log(`🔍 Running health check: ${check.name} (${checkId})`);
const result = await Promise.race([ const result = await Promise.race([
Promise.resolve(check.check()), Promise.resolve(check.check()),
@ -1001,7 +912,6 @@ class SystemLoader {
const duration = Date.now() - startTime; const duration = Date.now() - startTime;
const passed = Boolean(result); const passed = Boolean(result);
// console.log(`✅ Health check ${check.name}: ${passed ? 'PASSED' : 'FAILED'} (${duration}ms)`);
this.completedChecks += check.weight; this.completedChecks += check.weight;
this.progress = Math.min((this.completedChecks / this.totalChecks) * 100, 100); this.progress = Math.min((this.completedChecks / this.totalChecks) * 100, 100);
@ -1082,7 +992,6 @@ class SystemLoader {
// Check required config files // Check required config files
async checkConfigFiles() { async checkConfigFiles() {
// console.log('🔍 Config Files Check: Starting validation');
// Critical files that MUST exist and not be empty // Critical files that MUST exist and not be empty
const criticalFiles = [ const criticalFiles = [
@ -1099,7 +1008,6 @@ class SystemLoader {
'/data/config/generated/configs.json' '/data/config/generated/configs.json'
]; ];
// console.log('🔍 Critical files to check:', criticalFiles);
// Optional files (can be missing but should exist if possible) // Optional files (can be missing but should exist if possible)
const optionalFiles = [ const optionalFiles = [
@ -1117,34 +1025,26 @@ class SystemLoader {
for (const file of allFiles) { for (const file of allFiles) {
try { try {
// console.log(`🔍 Checking file: ${file}`);
const response = await fetch(file, { method: 'HEAD' }); const response = await fetch(file, { method: 'HEAD' });
// console.log(`📊 Response status: ${response.status} ${response.statusText}`);
// console.log(`📊 Content-Length: ${response.headers.get('content-length')}`);
// console.log(`📊 Response ok: ${response.ok}`);
if (response.ok) { if (response.ok) {
// Get content length to check if file is empty // Get content length to check if file is empty
const contentLength = response.headers.get('content-length'); const contentLength = response.headers.get('content-length');
const isEmpty = contentLength === '0' || contentLength === null; const isEmpty = contentLength === '0' || contentLength === null;
// console.log(`🔍 File ${file} - contentLength: ${contentLength}, isEmpty: ${isEmpty}`);
// For critical files, also check actual content // For critical files, also check actual content
if (criticalFiles.includes(file) && !isEmpty) { if (criticalFiles.includes(file) && !isEmpty) {
try { try {
const getResponse = await fetch(file); const getResponse = await fetch(file);
const content = await getResponse.text(); const content = await getResponse.text();
// console.log(`📄 Content preview for ${file}:`, content.substring(0, 100) + '...');
// Check if content starts with '{' or '[' (basic JSON file check) // Check if content starts with '{' or '[' (basic JSON file check)
const startsWithBrace = content.trim().startsWith('{'); const startsWithBrace = content.trim().startsWith('{');
const startsWithBracket = content.trim().startsWith('['); const startsWithBracket = content.trim().startsWith('[');
const isValidJSONStart = startsWithBrace || startsWithBracket; const isValidJSONStart = startsWithBrace || startsWithBracket;
// console.log(`🔍 JSON structure check for ${file}: starts with '{' or '['? ${isValidJSONStart} (content: ${content.trim().substring(0, 10)}...)`);
if (!isValidJSONStart) { if (!isValidJSONStart) {
// console.log(`❌ Critical file does not start with '{' or '[' (not valid JSON): ${file}`);
results.criticalEmpty.push(file); results.criticalEmpty.push(file);
results.empty.push(file); results.empty.push(file);
} }
@ -1152,7 +1052,6 @@ class SystemLoader {
else if (content.includes('404 Not Found') || content.includes('404') && content.includes('Not Found') || else if (content.includes('404 Not Found') || content.includes('404') && content.includes('Not Found') ||
(content.includes('Error') && (content.includes('<!DOCTYPE') || content.includes('<html>') || content.includes('status'))) || (content.includes('Error') && (content.includes('<!DOCTYPE') || content.includes('<html>') || content.includes('status'))) ||
content.includes('<!DOCTYPE') || content.includes('<html>')) { content.includes('<!DOCTYPE') || content.includes('<html>')) {
// console.log(`❌ Critical file contains error/fallback content: ${file}`);
results.criticalEmpty.push(file); results.criticalEmpty.push(file);
results.empty.push(file); results.empty.push(file);
} }
@ -1160,17 +1059,13 @@ class SystemLoader {
else { else {
try { try {
JSON.parse(content); JSON.parse(content);
// console.log(`✅ JSON syntax valid for: ${file}`);
results.available.push(file); results.available.push(file);
// console.log(`✅ File is available and valid: ${file}`);
} catch (jsonError) { } catch (jsonError) {
// console.log(`❌ Critical file has invalid JSON syntax: ${file} - ${jsonError.message}`);
results.criticalEmpty.push(file); results.criticalEmpty.push(file);
results.empty.push(file); results.empty.push(file);
} }
} }
} catch (contentError) { } catch (contentError) {
// console.log(`❌ Failed to read content for ${file}:`, contentError.message);
results.criticalEmpty.push(file); results.criticalEmpty.push(file);
results.empty.push(file); results.empty.push(file);
} }
@ -1178,39 +1073,24 @@ class SystemLoader {
results.empty.push(file); results.empty.push(file);
if (criticalFiles.includes(file)) { if (criticalFiles.includes(file)) {
results.criticalEmpty.push(file); results.criticalEmpty.push(file);
// console.log(`❌ Critical file is EMPTY: ${file}`);
} }
} else { } else {
results.available.push(file); results.available.push(file);
// console.log(`✅ File is available: ${file}`);
} }
} else { } else {
results.missing.push(file); results.missing.push(file);
if (criticalFiles.includes(file)) { if (criticalFiles.includes(file)) {
results.criticalMissing.push(file); results.criticalMissing.push(file);
// console.log(`❌ Critical file is MISSING: ${file}`);
} }
// console.log(`❌ File not accessible: ${file} - ${response.status} ${response.statusText}`);
} }
} catch (error) { } catch (error) {
// console.log(`❌ Exception checking file ${file}:`, error.message);
results.missing.push(file); results.missing.push(file);
if (criticalFiles.includes(file)) { if (criticalFiles.includes(file)) {
results.criticalMissing.push(file); results.criticalMissing.push(file);
// console.log(`❌ Critical file exception: ${file}`);
} }
} }
} }
// console.log('Config Files Results:', {
//available: results.available.length,
//missing: results.missing.length,
//empty: results.empty.length,
//criticalMissing: results.criticalMissing.length,
//criticalEmpty: results.criticalEmpty.length,
//missingFiles: results.missing,
//emptyFiles: results.empty
//});
// Fail if ANY critical files are missing or empty // Fail if ANY critical files are missing or empty
if (results.criticalMissing.length > 0 || results.criticalEmpty.length > 0) { if (results.criticalMissing.length > 0 || results.criticalEmpty.length > 0) {
@ -1226,19 +1106,16 @@ class SystemLoader {
throw new Error(errorMessage); throw new Error(errorMessage);
} }
// console.log('✅ Config Files Check PASSED');
return results; return results;
} }
// Check for update lock file to prevent concurrent updates // Check for update lock file to prevent concurrent updates
async checkUpdateLock() { async checkUpdateLock() {
// console.log('🔍 Update Lock Check: Checking for update lock file');
try { try {
const response = await fetch('/data/updater-lock', { method: 'HEAD' }); const response = await fetch('/data/updater-lock', { method: 'HEAD' });
const lockExists = response.ok; const lockExists = response.ok;
// console.log(`🔒 Update lock file exists: ${lockExists}`);
if (lockExists) { if (lockExists) {
return { return {
@ -1262,13 +1139,11 @@ class SystemLoader {
// Check for pause lock file to prevent operations during pause // Check for pause lock file to prevent operations during pause
async checkPauseLock() { async checkPauseLock() {
// console.log('🔍 Pause Lock Check: Checking for pause lock file');
try { try {
const response = await fetch('/data/pause.lock', { method: 'HEAD' }); const response = await fetch('/data/pause.lock', { method: 'HEAD' });
const lockExists = response.ok; const lockExists = response.ok;
// console.log(`🔒 Pause lock file exists: ${lockExists}`);
if (lockExists) { if (lockExists) {
return { return {
@ -1320,12 +1195,10 @@ class SystemLoader {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Check if script is already loaded // Check if script is already loaded
if (document.querySelector(`script[src="${src}"]`)) { if (document.querySelector(`script[src="${src}"]`)) {
// console.log(`📦 Script already loaded: ${src}`);
resolve(); resolve();
return; return;
} }
// console.log(`📦 Loading script: ${src}`);
const script = document.createElement('script'); const script = document.createElement('script');
script.src = src; script.src = src;
// Dynamically-inserted scripts default to async=true and run in whatever // Dynamically-inserted scripts default to async=true and run in whatever
@ -1335,7 +1208,6 @@ class SystemLoader {
// prototype). Mirrors the ordered kernel ctx.loadScripts() path. // prototype). Mirrors the ordered kernel ctx.loadScripts() path.
script.async = false; script.async = false;
script.onload = () => { script.onload = () => {
// console.log(`✅ Script loaded: ${src}`);
resolve(); resolve();
}; };
script.onerror = () => { script.onerror = () => {
@ -1350,9 +1222,7 @@ class SystemLoader {
async loadScripts(scripts) { async loadScripts(scripts) {
if (!scripts || scripts.length === 0) return; if (!scripts || scripts.length === 0) return;
// console.log(`📦 Loading ${scripts.length} scripts for component...`);
await Promise.all(scripts.map(script => this.loadScript(script))); await Promise.all(scripts.map(script => this.loadScript(script)));
// console.log(`✅ All scripts loaded for component`);
} }
} }

View File

@ -1,7 +1,6 @@
// Main System Orchestrator - Ties together loading, setup, and initialization // Main System Orchestrator - Ties together loading, setup, and initialization
class SystemOrchestrator { class SystemOrchestrator {
constructor() { constructor() {
// console.log('🏗️ SystemOrchestrator: Constructor called');
this.systemLoader = null; this.systemLoader = null;
this.loadingUI = null; this.loadingUI = null;
this.setupDetector = null; this.setupDetector = null;
@ -11,14 +10,11 @@ class SystemOrchestrator {
// Initialize the entire system // Initialize the entire system
async initialize() { async initialize() {
// console.log('🚀 SystemOrchestrator: initialize() called');
if (this.isInitialized) { if (this.isInitialized) {
// console.log('🔄 SystemOrchestrator: Already initialized, returning existing promise');
return this.loadingPromise; return this.loadingPromise;
} }
// console.log('🆕 SystemOrchestrator: Starting initialization...');
try { try {
// Auth gate — must complete before anything else loads or fetches data // Auth gate — must complete before anything else loads or fetches data
if (window.authManager) { if (window.authManager) {
@ -26,20 +22,15 @@ class SystemOrchestrator {
window.authManager.interceptFetch(); window.authManager.interceptFetch();
} }
// console.log('🚀 System Orchestrator: Initializing...');
// Initialize components // Initialize components
// console.log('🔧 SystemOrchestrator: Creating SystemLoader...');
this.systemLoader = new SystemLoader(); this.systemLoader = new SystemLoader();
// console.log('🎨 SystemOrchestrator: Creating LoadingUI...');
this.loadingUI = new LoadingUI(); this.loadingUI = new LoadingUI();
// console.log('🔍 SystemOrchestrator: Creating SetupDetector...');
this.setupDetector = new SetupDetector(); this.setupDetector = new SetupDetector();
// Show loading screen // Show loading screen
// console.log('📺 SystemOrchestrator: Showing loading screen...');
this.loadingUI.initialize(); this.loadingUI.initialize();
// Setup event listeners // Setup event listeners
@ -54,18 +45,15 @@ class SystemOrchestrator {
})(); })();
if (setupStatus.isFirstTime && !hasActiveHandoff) { if (setupStatus.isFirstTime && !hasActiveHandoff) {
// console.log('🔧 First-time setup detected');
await this.handleFirstTimeSetup(); await this.handleFirstTimeSetup();
} else if (setupStatus.isFirstTime && hasActiveHandoff) { } else if (setupStatus.isFirstTime && hasActiveHandoff) {
console.log('[orchestrator] setup handoff in progress, skipping wizard'); console.log('[orchestrator] setup handoff in progress, skipping wizard');
await this.handleNormalLoading(); await this.handleNormalLoading();
} else { } else {
// console.log('✅ Returning user detected, proceeding with normal loading');
await this.handleNormalLoading(); await this.handleNormalLoading();
} }
this.isInitialized = true; this.isInitialized = true;
// console.log('✅ System Orchestrator: Initialization complete');
} catch (error) { } catch (error) {
console.error('❌ System Orchestrator: Initialization failed:', error); console.error('❌ System Orchestrator: Initialization failed:', error);
@ -97,7 +85,6 @@ class SystemOrchestrator {
}); });
this.systemLoader.on('onComplete', (data) => { this.systemLoader.on('onComplete', (data) => {
// console.log('✅ System Loader completed:', data.success ? 'SUCCESS' : 'FAILED');
// Don't show errors here - let handleNormalLoading handle all error display logic // Don't show errors here - let handleNormalLoading handle all error display logic
if (data.success) { if (data.success) {
@ -118,7 +105,6 @@ class SystemOrchestrator {
// Handle first-time setup // Handle first-time setup
async handleFirstTimeSetup() { async handleFirstTimeSetup() {
// console.log('🎯 Starting first-time setup flow...');
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
// Create and show setup wizard // Create and show setup wizard
@ -139,7 +125,6 @@ class SystemOrchestrator {
// Handle normal loading sequence // Handle normal loading sequence
async handleNormalLoading() { async handleNormalLoading() {
// console.log('📊 Starting normal loading sequence...');
// Wait longer for all scripts to fully load // Wait longer for all scripts to fully load
await new Promise(resolve => setTimeout(resolve, 2500)); await new Promise(resolve => setTimeout(resolve, 2500));
@ -156,7 +141,6 @@ class SystemOrchestrator {
if (missingDataFiles.length > 0) { if (missingDataFiles.length > 0) {
console.warn('⚠️ Missing LibrePortal data files detected'); console.warn('⚠️ Missing LibrePortal data files detected');
// console.log('🔍 Showing enhanced error for missing data files');
// Show enhanced error message with setup instructions // Show enhanced error message with setup instructions
const enhancedErrors = results.errors.map(error => { const enhancedErrors = results.errors.map(error => {
@ -178,21 +162,16 @@ class SystemOrchestrator {
// Listen for continue button click // Listen for continue button click
window.addEventListener('loadingContinue', () => { window.addEventListener('loadingContinue', () => {
// console.log('🔄 User chose to continue despite errors');
this.proceedToApplicationWithErrors(); this.proceedToApplicationWithErrors();
}, { once: true }); // Remove listener after first use }, { once: true }); // Remove listener after first use
this.errorAlreadyHandled = true; this.errorAlreadyHandled = true;
// console.log('🔍 Set errorAlreadyHandled = true, returning early');
return; // Prevent reaching the general error handling below return; // Prevent reaching the general error handling below
} }
if (results.success) { if (results.success) {
// console.log('✅ All systems passed health checks');
// Initialize all components (even if some health checks failed) // Initialize all components (even if some health checks failed)
// console.log('🚨 BREAKPOINT: About to call initializeComponents()');
await this.systemLoader.initializeComponents(); await this.systemLoader.initializeComponents();
// console.log('🚨 BREAKPOINT: initializeComponents() completed');
// Hide loading screen only if everything is successful // Hide loading screen only if everything is successful
this.loadingUI.hide(); this.loadingUI.hide();
@ -201,21 +180,17 @@ class SystemOrchestrator {
this.initializeOriginalSPA(); this.initializeOriginalSPA();
this.proceedToApplication(); this.proceedToApplication();
} else { } else {
// console.log('🔍 General error handling - errorAlreadyHandled:', this.errorAlreadyHandled);
console.error('❌ Critical systems failed:', results.errors); console.error('❌ Critical systems failed:', results.errors);
console.error('❌ Failed systems details:', JSON.stringify(results.errors, null, 2)); console.error('❌ Failed systems details:', JSON.stringify(results.errors, null, 2));
// Show errors in loading UI and keep it visible (only if not already handled) // Show errors in loading UI and keep it visible (only if not already handled)
if (!this.errorAlreadyHandled) { if (!this.errorAlreadyHandled) {
// console.log('🔍 Showing general error (not already handled)');
this.loadingUI.showError(results.errors); this.loadingUI.showError(results.errors);
} else { } else {
// console.log('🔍 Skipping general error display (already handled)');
} }
// Listen for continue button click // Listen for continue button click
window.addEventListener('loadingContinue', () => { window.addEventListener('loadingContinue', () => {
// console.log('🔄 User chose to continue despite errors');
this.proceedToApplicationWithErrors(); this.proceedToApplicationWithErrors();
}, { once: true }); // Remove listener after first use }, { once: true }); // Remove listener after first use
} }
@ -223,7 +198,6 @@ class SystemOrchestrator {
// Proceed to main application // Proceed to main application
proceedToApplication() { proceedToApplication() {
// console.log('🎯 Proceeding to main application...');
// Don't initialize SPA here - wait for component initialization to complete // Don't initialize SPA here - wait for component initialization to complete
// SPA will be initialized after all components are ready // SPA will be initialized after all components are ready
@ -231,12 +205,9 @@ class SystemOrchestrator {
// Proceed with application despite errors (user choice) // Proceed with application despite errors (user choice)
async proceedToApplicationWithErrors() { async proceedToApplicationWithErrors() {
// console.log('🎯 Proceeding with application despite errors...');
// Initialize components even though some checks failed // Initialize components even though some checks failed
// console.log('🚨 BREAKPOINT: About to call initializeComponents() with errors');
await this.systemLoader.initializeComponents(); await this.systemLoader.initializeComponents();
// console.log('🚨 BREAKPOINT: initializeComponents() completed with errors');
// Hide loading screen and proceed // Hide loading screen and proceed
this.loadingUI.hide(); this.loadingUI.hide();
@ -249,25 +220,19 @@ class SystemOrchestrator {
// Initialize the original SPA system // Initialize the original SPA system
initializeOriginalSPA() { initializeOriginalSPA() {
// console.log('🔄 Initializing original SPA...');
if (typeof window.spaClean !== 'undefined') { if (typeof window.spaClean !== 'undefined') {
// console.log('✅ SPA instance already initialized by SystemLoader');
// Now manually call the SPA's init method since we prevented auto-initialization // Now manually call the SPA's init method since we prevented auto-initialization
if (typeof window.spaClean.init === 'function') { if (typeof window.spaClean.init === 'function') {
// console.log('🔄 Manually calling SPA init()...');
window.spaClean.init().then(() => { window.spaClean.init().then(() => {
// console.log('✅ SPA initialization completed');
}).catch(error => { }).catch(error => {
console.error('❌ SPA initialization failed:', error); console.error('❌ SPA initialization failed:', error);
}); });
} }
} else if (typeof LibrePortalSPAClean !== 'undefined') { } else if (typeof LibrePortalSPAClean !== 'undefined') {
// console.log('🔄 Creating SPA instance manually...');
window.spaClean = new LibrePortalSPAClean(); window.spaClean = new LibrePortalSPAClean();
// console.log('✅ SPA instance created');
} else { } else {
console.error('❌ SPA class not available'); console.error('❌ SPA class not available');
return; return;
@ -294,7 +259,6 @@ class SystemOrchestrator {
// Retry initialization // Retry initialization
async retryInitialization() { async retryInitialization() {
// console.log('🔄 Retrying initialization...');
// Reset UI // Reset UI
this.loadingUI.reset(); this.loadingUI.reset();
@ -347,7 +311,6 @@ class SystemOrchestrator {
// Force re-initialization (for testing) // Force re-initialization (for testing)
async forceReinitialize() { async forceReinitialize() {
// console.log('🔄 Force re-initializing...');
// Clean up // Clean up
if (this.loadingUI && this.loadingUI.isVisible) { if (this.loadingUI && this.loadingUI.isVisible) {
@ -368,15 +331,12 @@ window.SystemOrchestrator = SystemOrchestrator;
// Auto-initialize when DOM is ready // Auto-initialize when DOM is ready
if (document.readyState === 'loading') { if (document.readyState === 'loading') {
// console.log('🔄 SystemOrchestrator: DOM not ready, adding listener');
document.addEventListener('DOMContentLoaded', async () => { document.addEventListener('DOMContentLoaded', async () => {
// console.log('🚀 SystemOrchestrator: DOM ready, initializing...');
window.systemOrchestrator = new SystemOrchestrator(); window.systemOrchestrator = new SystemOrchestrator();
await window.systemOrchestrator.initialize(); await window.systemOrchestrator.initialize();
}); });
} else { } else {
// DOM already ready // DOM already ready
// console.log('🚀 SystemOrchestrator: DOM already ready, initializing immediately...');
(async () => { (async () => {
window.systemOrchestrator = new SystemOrchestrator(); window.systemOrchestrator = new SystemOrchestrator();
await window.systemOrchestrator.initialize(); await window.systemOrchestrator.initialize();

View File

@ -93,7 +93,6 @@ class ConfigShared {
// Auto-detect and create appropriate field type // Auto-detect and create appropriate field type
static createSmartField(fieldId, key, value, title, description, options = {}) { static createSmartField(fieldId, key, value, title, description, options = {}) {
//console.log(`createSmartField: key=${key}, value=${value}, config=${!!options.config}`);
// Check if value is boolean (true/false strings) // Check if value is boolean (true/false strings)
const isBoolean = value === 'true' || value === 'false'; const isBoolean = value === 'true' || value === 'false';
@ -115,7 +114,6 @@ class ConfigShared {
// Handle standard toggle changes // Handle standard toggle changes
static handleToggleChange(checkbox, key, category) { static handleToggleChange(checkbox, key, category) {
//console.log(`Toggle changed: ${key} = ${checkbox.checked} (category: ${category})`);
// Trigger custom event for other components to listen to // Trigger custom event for other components to listen to
const event = new CustomEvent('configToggleChanged', { const event = new CustomEvent('configToggleChanged', {
@ -131,7 +129,6 @@ class ConfigShared {
// Handle master toggle changes (enables/disables multiple fields) // Handle master toggle changes (enables/disables multiple fields)
static handleMasterToggle(checkbox, sectionId, fieldIds) { static handleMasterToggle(checkbox, sectionId, fieldIds) {
//console.log(`Master toggle changed: ${sectionId} = ${checkbox.checked}`);
// Enable/disable related fields // Enable/disable related fields
if (fieldIds && fieldIds.length > 0) { if (fieldIds && fieldIds.length > 0) {
@ -161,7 +158,6 @@ class ConfigShared {
// Handle section toggle changes (shows/hides sections) // Handle section toggle changes (shows/hides sections)
static handleSectionToggle(checkbox, sectionId) { static handleSectionToggle(checkbox, sectionId) {
//console.log(`Section toggle changed: ${sectionId} = ${checkbox.checked}`);
const content = document.getElementById(`${sectionId}-content`); const content = document.getElementById(`${sectionId}-content`);
if (content) { if (content) {
@ -179,7 +175,6 @@ class ConfigShared {
static async saveToggleValue(key, value) { static async saveToggleValue(key, value) {
try { try {
// For now, just log the change - local implementation // For now, just log the change - local implementation
//console.log('Toggle value changed:', key, value ? 'true' : 'false');
// TODO: Implement local config file update // TODO: Implement local config file update
// This would require backend integration to write to actual config files // This would require backend integration to write to actual config files
@ -355,7 +350,6 @@ class ConfigShared {
const crontabValue = `${minute} ${cronHour} * * *`; const crontabValue = `${minute} ${cronHour} * * *`;
hiddenInput.value = crontabValue; hiddenInput.value = crontabValue;
//console.log(`Updated crontab for ${key}: ${crontabValue}`);
} }
// Toggle password visibility // Toggle password visibility
@ -530,7 +524,6 @@ class ConfigShared {
// Generate appropriate field based on value type and key // Generate appropriate field based on value type and key
static generateField(fieldId, key, value, title, description, options = {}, allConfig = {}) { static generateField(fieldId, key, value, title, description, options = {}, allConfig = {}) {
//console.log(`generateField: key=${key}, value=${value}, CFG_INSTALL_MODE=${allConfig.CFG_INSTALL_MODE?.value}`);
// Note: Git fields (CFG_GIT_*) are now handled by the toggle system in renderGitSection // Note: Git fields (CFG_GIT_*) are now handled by the toggle system in renderGitSection
// They don't need to be hidden here since the section itself is toggled // They don't need to be hidden here since the section itself is toggled
@ -730,14 +723,11 @@ class ConfigShared {
} else if (key.includes('TIMEZONE')) { } else if (key.includes('TIMEZONE')) {
// Special handling for Timezone - create comprehensive timezone dropdown // Special handling for Timezone - create comprehensive timezone dropdown
const timezoneOptions = ConfigOptions.getTimezoneOptions(); const timezoneOptions = ConfigOptions.getTimezoneOptions();
//console.log('Timezone key:', key, 'Current value:', value, 'Type:', typeof value);
//console.log('Available timezone options:', timezoneOptions.map(opt => ({value: opt.value, label: opt.label})));
fieldHTML += ` fieldHTML += `
<select id="${fieldId}" name="${key}" class="form-control"> <select id="${fieldId}" name="${key}" class="form-control">
${timezoneOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')} ${timezoneOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}
</select> </select>
`; `;
//console.log('Generated timezone dropdown HTML for', key, 'with value', value);
} else if (key === 'CFG_INSTALL_MODE') { } else if (key === 'CFG_INSTALL_MODE') {
const selectOptions = ConfigOptions.getSelectOptions(key); const selectOptions = ConfigOptions.getSelectOptions(key);
fieldHTML += `<select id="${fieldId}" name="${key}" class="form-control" onchange="handleInstallModeChange(this)">${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}</select>`; fieldHTML += `<select id="${fieldId}" name="${key}" class="form-control" onchange="handleInstallModeChange(this)">${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}</select>`;
@ -745,25 +735,17 @@ class ConfigShared {
const selectOptions = ConfigOptions.getSelectOptions(key); const selectOptions = ConfigOptions.getSelectOptions(key);
fieldHTML += `<select id="${fieldId}" name="${key}" class="form-control">${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}</select>`; fieldHTML += `<select id="${fieldId}" name="${key}" class="form-control">${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}</select>`;
} else if (ConfigOptions.isDropdownKey(key) || (options && Object.keys(options).length > 0)) { } else if (ConfigOptions.isDropdownKey(key) || (options && Object.keys(options).length > 0)) {
//console.log('=== GENERIC DROPDOWN BLOCK ENTERED for key:', key);
//console.log('Dropdown detected for key:', key);
//console.log('isDropdownKey result:', ConfigOptions.isDropdownKey(key));
//console.log('options available:', options);
const selectOptions = (options && typeof options === 'string') ? this.parseOptions(options) : ConfigOptions.getSelectOptions(key); const selectOptions = (options && typeof options === 'string') ? this.parseOptions(options) : ConfigOptions.getSelectOptions(key);
//console.log('selectOptions:', selectOptions);
fieldHTML += ` fieldHTML += `
<select id="${fieldId}" name="${key}" class="form-control"> <select id="${fieldId}" name="${key}" class="form-control">
${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')} ${selectOptions.map(opt => `<option value="${opt.value}" ${opt.value === value ? 'selected' : ''}>${opt.label}</option>`).join('')}
</select> </select>
`; `;
//console.log('Generated dropdown for', key, 'with value', value);
} else if (key.includes('DESCRIPTION') || key.includes('COMMENTS') || key.includes('NOTES')) { } else if (key.includes('DESCRIPTION') || key.includes('COMMENTS') || key.includes('NOTES')) {
//console.log('Textarea detected for key:', key);
fieldHTML += ` fieldHTML += `
<textarea id="${fieldId}" name="${key}" class="form-control" rows="4">${value}</textarea> <textarea id="${fieldId}" name="${key}" class="form-control" rows="4">${value}</textarea>
`; `;
} else { } else {
//console.log('Default text input for key:', key);
// Default text input with event handlers and options // Default text input with event handlers and options
const inputClass = className ? `form-control ${className}` : 'form-control'; const inputClass = className ? `form-control ${className}` : 'form-control';
const inputPlaceholder = placeholder || ''; const inputPlaceholder = placeholder || '';
@ -832,7 +814,6 @@ class ConfigShared {
fieldGroup.style.pointerEvents = 'auto'; fieldGroup.style.pointerEvents = 'auto';
} }
}); });
//console.log(`Section ${sectionId} enabled`);
} else { } else {
// Disable section // Disable section
sectionContent.classList.add('disabled'); sectionContent.classList.add('disabled');
@ -844,7 +825,6 @@ class ConfigShared {
fieldGroup.style.pointerEvents = 'none'; fieldGroup.style.pointerEvents = 'none';
} }
}); });
//console.log(`Section ${sectionId} disabled`);
} }
} }
@ -860,11 +840,9 @@ class ConfigShared {
if (isEnabled) { if (isEnabled) {
// Show section // Show section
sectionContent.classList.remove('hidden'); sectionContent.classList.remove('hidden');
//console.log(`Section ${sectionId} shown`);
} else { } else {
// Hide section // Hide section
sectionContent.classList.add('hidden'); sectionContent.classList.add('hidden');
//console.log(`Section ${sectionId} hidden`);
} }
} }
@ -931,22 +909,15 @@ class ConfigShared {
// Universal toggle function for all _ENABLED options // Universal toggle function for all _ENABLED options
static toggleSection(sectionId, isEnabled) { static toggleSection(sectionId, isEnabled) {
//console.log('=== UNIVERSAL TOGGLE DEBUG ===');
//console.log('sectionId:', sectionId);
//console.log('isEnabled:', isEnabled);
const sectionContent = document.getElementById(sectionId); const sectionContent = document.getElementById(sectionId);
const fields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea'); const fields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
//console.log('sectionContent found:', !!sectionContent);
//console.log('fields found:', fields ? fields.length : 0);
if (sectionContent && fields) { if (sectionContent && fields) {
if (isEnabled) { if (isEnabled) {
//console.log('Enabling section...');
sectionContent.classList.remove('hidden'); sectionContent.classList.remove('hidden');
fields.forEach((field, index) => { fields.forEach((field, index) => {
//console.log(`Enabling field ${index}:`, field);
field.disabled = false; field.disabled = false;
const fieldGroup = field?.closest('.field-group'); const fieldGroup = field?.closest('.field-group');
if (fieldGroup) { if (fieldGroup) {
@ -955,10 +926,8 @@ class ConfigShared {
} }
}); });
} else { } else {
//console.log('Disabling section...');
sectionContent.classList.add('hidden'); sectionContent.classList.add('hidden');
fields.forEach((field, index) => { fields.forEach((field, index) => {
//console.log(`Disabling field ${index}:`, field);
field.disabled = true; field.disabled = true;
const fieldGroup = field?.closest('.field-group'); const fieldGroup = field?.closest('.field-group');
if (fieldGroup) { if (fieldGroup) {
@ -969,51 +938,34 @@ class ConfigShared {
} }
} }
//console.log('=== UNIVERSAL TOGGLE DEBUG END ===');
} }
// Remote backup section toggle function // Remote backup section toggle function
static toggleMailSection(sectionId, isEnabled) { static toggleMailSection(sectionId, isEnabled) {
//console.log('=== TOGGLE MAIL SECTION DEBUG ===');
//console.log('sectionId:', sectionId);
//console.log('isEnabled:', isEnabled);
alert('toggleMailSection called: ' + sectionId + ', enabled: ' + isEnabled); alert('toggleMailSection called: ' + sectionId + ', enabled: ' + isEnabled);
//console.log('Looking for sectionContent...');
const sectionContent = document.getElementById(sectionId); const sectionContent = document.getElementById(sectionId);
//console.log('sectionContent found:', !!sectionContent);
//console.log('Looking for mailFields...');
const mailFields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea'); const mailFields = sectionContent?.querySelectorAll('.config-fields input, .config-fields select, .config-fields textarea');
//console.log('mailFields found:', mailFields ? mailFields.length : 0);
if (sectionContent && mailFields) { if (sectionContent && mailFields) {
//console.log('Enabling mail section...');
if (isEnabled) { if (isEnabled) {
//console.log('Removing hidden class...');
sectionContent.classList.remove('hidden'); sectionContent.classList.remove('hidden');
//console.log('Enabling fields...');
mailFields.forEach((field, index) => { mailFields.forEach((field, index) => {
//console.log(`Disabling field ${index}:`, field);
field.disabled = false; field.disabled = false;
const fieldGroup = field?.closest('.field-group'); const fieldGroup = field?.closest('.field-group');
if (fieldGroup) { if (fieldGroup) {
//console.log('Enabling field group...');
fieldGroup.style.opacity = '1'; fieldGroup.style.opacity = '1';
fieldGroup.style.pointerEvents = 'auto'; fieldGroup.style.pointerEvents = 'auto';
} }
}); });
} else { } else {
//console.log('Disabling mail section...');
sectionContent.classList.add('hidden'); sectionContent.classList.add('hidden');
//console.log('Disabling fields...');
mailFields.forEach((field, index) => { mailFields.forEach((field, index) => {
//console.log(`Enabling field ${index}:`, field);
field.disabled = true; field.disabled = true;
const fieldGroup = field?.closest('.field-group'); const fieldGroup = field?.closest('.field-group');
if (fieldGroup) { if (fieldGroup) {
//console.log('Disabling field group...');
fieldGroup.style.opacity = '0.5'; fieldGroup.style.opacity = '0.5';
fieldGroup.style.pointerEvents = 'none'; fieldGroup.style.pointerEvents = 'none';
} }
@ -1021,7 +973,6 @@ class ConfigShared {
} }
} }
//console.log('=== TOGGLE MAIL SECTION DEBUG END ===');
} }
static toggleRemoteBackupSection(sectionId, isEnabled) { static toggleRemoteBackupSection(sectionId, isEnabled) {
@ -1488,7 +1439,6 @@ window.ConfigShared = ConfigShared;
// Global toggle change function for checkbox handling // Global toggle change function for checkbox handling
window.handleToggleChange = function(checkbox, key) { window.handleToggleChange = function(checkbox, key) {
//console.log(`Toggle changed: ${key} = ${checkbox.checked}`);
// This function can be extended to handle specific toggle logic // This function can be extended to handle specific toggle logic
// For now, it just logs change // For now, it just logs change
}; };
@ -1500,12 +1450,10 @@ window.isReloadingConfig = false;
window.handleInstallModeChange = function(selectElement) { window.handleInstallModeChange = function(selectElement) {
// Prevent multiple simultaneous reloads // Prevent multiple simultaneous reloads
if (window.isReloadingConfig) { if (window.isReloadingConfig) {
//console.log('Config reload already in progress, ignoring...');
return; return;
} }
const installMode = selectElement.value; const installMode = selectElement.value;
//console.log(`Install mode changed to: ${installMode}`);
// Set flag to prevent multiple reloads // Set flag to prevent multiple reloads
window.isReloadingConfig = true; window.isReloadingConfig = true;
@ -1515,11 +1463,9 @@ window.handleInstallModeChange = function(selectElement) {
if (window.configManager) { if (window.configManager) {
// Clear cache to ensure we get fresh data with updated CFG_INSTALL_MODE // Clear cache to ensure we get fresh data with updated CFG_INSTALL_MODE
window.configManager.cache.clear(); window.configManager.cache.clear();
//console.log('Cache cleared for fresh config data');
// Get the current category from the URL or default to 'general' // Get the current category from the URL or default to 'general'
const currentCategory = window.configCategory || 'general'; const currentCategory = window.configCategory || 'general';
//console.log(`Reloading config category: ${currentCategory}`);
window.configManager.renderConfig(currentCategory).finally(() => { window.configManager.renderConfig(currentCategory).finally(() => {
// Clear the flag after reload is complete // Clear the flag after reload is complete
setTimeout(() => { setTimeout(() => {
@ -1529,7 +1475,6 @@ window.handleInstallModeChange = function(selectElement) {
} else if (window.configRouter) { } else if (window.configRouter) {
// Fallback to configRouter if configManager is not available // Fallback to configRouter if configManager is not available
const currentCategory = window.configCategory || 'general'; const currentCategory = window.configCategory || 'general';
//console.log(`Using configRouter to reload: ${currentCategory}`);
window.configRouter.loadConfigComponentManual(currentCategory).finally(() => { window.configRouter.loadConfigComponentManual(currentCategory).finally(() => {
// Clear the flag after reload is complete // Clear the flag after reload is complete
setTimeout(() => { setTimeout(() => {

View File

@ -184,7 +184,6 @@ class ConfigOptions {
// Get select options for specific config keys // Get select options for specific config keys
static getSelectOptions(key) { static getSelectOptions(key) {
//console.log('=== getSelectOptions ENTRY === called with:', key);
const optionMaps = { const optionMaps = {
'CFG_DOCKER_INSTALL_TYPE': [ 'CFG_DOCKER_INSTALL_TYPE': [
{ value: 'rooted', label: 'Rooted' }, { value: 'rooted', label: 'Rooted' },
@ -274,7 +273,6 @@ class ConfigOptions {
} }
const result = optionMaps[key] || []; const result = optionMaps[key] || [];
//console.log('Final result for', key, ':', result);
return result; return result;
} }
@ -330,7 +328,6 @@ class ConfigOptions {
// Check if a config key should use dropdown // Check if a config key should use dropdown
static isDropdownKey(key) { static isDropdownKey(key) {
//console.log('ConfigOptions.isDropdownKey called with:', key);
const result = key === 'CFG_DOCKER_INSTALL_TYPE' || const result = key === 'CFG_DOCKER_INSTALL_TYPE' ||
key === 'CFG_UFW_LOGGING' || key === 'CFG_UFW_LOGGING' ||
key === 'CFG_TEXT_EDITOR' || key === 'CFG_TEXT_EDITOR' ||
@ -345,7 +342,6 @@ class ConfigOptions {
key === 'CFG_GLUETUN_VPN_SERVICE_PROVIDER' || key === 'CFG_GLUETUN_VPN_SERVICE_PROVIDER' ||
key === 'CFG_GLUETUN_VPN_TYPE' || key === 'CFG_GLUETUN_VPN_TYPE' ||
key === 'CFG_TRAEFIK_DASHBOARD_ACCESS'; key === 'CFG_TRAEFIK_DASHBOARD_ACCESS';
//console.log('ConfigOptions.isDropdownKey result:', result);
return result; return result;
} }
@ -357,11 +353,9 @@ class ConfigOptions {
// Fetch available domains from system configuration // Fetch available domains from system configuration
static async getAvailableDomains() { static async getAvailableDomains() {
try { try {
//console.log('🔍 Starting domain fetch...');
// Try to load system config to get domain information // Try to load system config to get domain information
const response = await fetch('/data/config/generated/configs.json'); const response = await fetch('/data/config/generated/configs.json');
//console.log('📡 Config response status:', response.status);
if (!response.ok) { if (!response.ok) {
console.warn('Could not load system config for domains, returning empty list'); console.warn('Could not load system config for domains, returning empty list');
@ -369,12 +363,8 @@ class ConfigOptions {
} }
const configData = await response.json(); const configData = await response.json();
//console.log('📄 Full config data:', configData);
//console.log('🔧 Config keys available:', Object.keys(configData));
const config = configData.config || {}; const config = configData.config || {};
//console.log('⚙️ Config object:', config);
//console.log('🔑 Config keys:', Object.keys(config));
const domains = []; const domains = [];
@ -382,7 +372,6 @@ class ConfigOptions {
for (let i = 1; i <= 9; i++) { for (let i = 1; i <= 9; i++) {
const domainKey = `CFG_DOMAIN_${i}`; const domainKey = `CFG_DOMAIN_${i}`;
const domainValue = config[domainKey]?.value || config[domainKey] || ''; const domainValue = config[domainKey]?.value || config[domainKey] || '';
//console.log(`🌐 Checking ${domainKey}:`, domainValue);
if (domainValue.trim() !== '') { if (domainValue.trim() !== '') {
domains.push({ domains.push({
@ -393,7 +382,6 @@ class ConfigOptions {
} }
} }
//console.log('✅ Found configured domains:', domains);
return domains; return domains;
} catch (error) { } catch (error) {
@ -404,12 +392,9 @@ class ConfigOptions {
// Get domain options for DOMAIN field // Get domain options for DOMAIN field
static async getDomainOptions() { static async getDomainOptions() {
//console.log('🎯 Getting domain options...');
const domains = await this.getAvailableDomains(); const domains = await this.getAvailableDomains();
//console.log('📊 Domains returned:', domains);
if (domains.length === 0) { if (domains.length === 0) {
//console.log('⚠️ No domains found, returning fallback option');
// No domains configured - return empty option // No domains configured - return empty option
return [ return [
{ value: '1', label: 'No domains configured - Configure domains in Network settings first' } { value: '1', label: 'No domains configured - Configure domains in Network settings first' }
@ -422,7 +407,6 @@ class ConfigOptions {
label: domain.domain label: domain.domain
})); }));
//console.log('✅ Generated domain options:', options);
return options; return options;
} }

View File

@ -56,7 +56,6 @@ class DataLoader {
static async getContainers() { static async getContainers() {
try { try {
// Local implementation - return empty array for now // Local implementation - return empty array for now
//console.log('Loading containers locally...');
// TODO: Implement local container detection // TODO: Implement local container detection
// This would require backend integration to query Docker // This would require backend integration to query Docker
@ -72,14 +71,12 @@ class DataLoader {
static async loadSystemConfigs() { static async loadSystemConfigs() {
try { try {
//console.log('Loading system configs');
// Load unified config // Load unified config
try { try {
const response = await fetch('/data/config/generated/configs.json'); const response = await fetch('/data/config/generated/configs.json');
if (response.ok) { if (response.ok) {
const data = await response.json(); const data = await response.json();
//console.log('✅ Loaded unified system config');
return data; return data;
} else { } else {
console.warn('Failed to load unified config:', response.status); console.warn('Failed to load unified config:', response.status);
@ -97,7 +94,6 @@ class DataLoader {
static async loadConfig(configType) { static async loadConfig(configType) {
try { try {
//console.log(`Loading ${configType} config`);
const response = await fetch(`/data/config/generated/config_${configType}.json`); const response = await fetch(`/data/config/generated/config_${configType}.json`);
if (!response.ok) { if (!response.ok) {
@ -170,7 +166,6 @@ let lastSystemDataHash = null;
// Dashboard-specific data loading // Dashboard-specific data loading
async function loadDashboardData() { async function loadDashboardData() {
// console.log('🔄 Loading dashboard data...');
// Load all apps with installation status // Load all apps with installation status
const allApps = await DataLoader.loadApps(); const allApps = await DataLoader.loadApps();
@ -215,7 +210,6 @@ async function loadDashboardData() {
// Show/refresh the "out of date" banner on the dashboard. // Show/refresh the "out of date" banner on the dashboard.
window.updateNotifier?.renderDashboardBanner(); window.updateNotifier?.renderDashboardBanner();
// console.log('✅ Dashboard data loaded successfully');
} }
// Countdown timer for next automatic update // Countdown timer for next automatic update
@ -297,7 +291,6 @@ function getTimeAgo(date) {
// Apps page data loading // Apps page data loading
async function loadAppsPageData() { async function loadAppsPageData() {
//console.log('Loading apps page data (all apps + categories)...');
// Load apps and categories in parallel // Load apps and categories in parallel
try { try {
@ -307,18 +300,11 @@ async function loadAppsPageData() {
DataLoader.loadConfigCategories() DataLoader.loadConfigCategories()
]); ]);
//console.log('🔍 DataLoader Results:');
//console.log(' - appsData length:', appsData?.length || 0);
//console.log(' - sidebarCategoriesData type:', typeof sidebarCategoriesData);
//console.log(' - sidebarCategoriesData keys:', Object.keys(sidebarCategoriesData || {}));
//console.log(' - configCategoriesData type:', typeof configCategoriesData);
//console.log(' - configCategoriesData keys:', Object.keys(configCategoriesData || {}));
apps = appsData; apps = appsData;
categories = sidebarCategoriesData; // For sidebar categories = sidebarCategoriesData; // For sidebar
systemConfigs = []; // Apps page doesn't need system configs systemConfigs = []; // Apps page doesn't need system configs
//console.log(`Apps page loaded: ${apps.length} apps, ${categories.length} categories`);
////console.log('Apps array:', apps); ////console.log('Apps array:', apps);
////console.log('Categories array:', categories); ////console.log('Categories array:', categories);
@ -381,7 +367,6 @@ async function loadConfigDetailData() {
// Load system information for dashboard // Load system information for dashboard
async function loadSystemInfo() { async function loadSystemInfo() {
try { try {
//console.log('Loading system data');
// Add timestamp to prevent browser caching // Add timestamp to prevent browser caching
const timestamp = Date.now(); const timestamp = Date.now();
@ -399,9 +384,6 @@ async function loadSystemInfo() {
const diskData = await diskResponse.json(); const diskData = await diskResponse.json();
const memoryData = await memoryResponse.json(); const memoryData = await memoryResponse.json();
//console.log('System data:', systemData);
//console.log('Disk data:', diskData);
//console.log('Memory data:', memoryData);
// Prepare system data // Prepare system data
const osInfo = systemData.os || 'Unknown'; const osInfo = systemData.os || 'Unknown';
@ -411,7 +393,6 @@ async function loadSystemInfo() {
osInfo.split(' ')[0]; // Take first part like "Linux" osInfo.split(' ')[0]; // Take first part like "Linux"
const diskChartData = diskData.root || diskData; const diskChartData = diskData.root || diskData;
//console.log('Disk chart data:', diskChartData);
// Wait for all dashboard elements to be available // Wait for all dashboard elements to be available
await waitForDashboardElements(); await waitForDashboardElements();
@ -423,14 +404,12 @@ async function loadSystemInfo() {
if (systemInfoEl) { if (systemInfoEl) {
systemInfoEl.textContent = cleanOs; systemInfoEl.textContent = cleanOs;
// console.log('✅ Updated OS:', cleanOs);
} else { } else {
console.warn('⚠️ system-info element not found'); console.warn('⚠️ system-info element not found');
} }
if (uptimeEl) { if (uptimeEl) {
uptimeEl.textContent = systemData.uptime || 'Unknown'; uptimeEl.textContent = systemData.uptime || 'Unknown';
// console.log('✅ Updated uptime:', systemData.uptime);
} else { } else {
console.warn('⚠️ uptime-info element not found'); console.warn('⚠️ uptime-info element not found');
} }
@ -438,7 +417,6 @@ async function loadSystemInfo() {
// Update memory info - use the text field which should be properly formatted // Update memory info - use the text field which should be properly formatted
if (memoryEl) { if (memoryEl) {
memoryEl.textContent = memoryData.text || 'Unknown'; memoryEl.textContent = memoryData.text || 'Unknown';
// console.log('✅ Updated memory:', memoryData.text);
} else { } else {
console.warn('⚠️ memory-info element not found'); console.warn('⚠️ memory-info element not found');
} }
@ -636,7 +614,6 @@ function updateDiskChart(data) {
// Minimal data loading (fallback) // Minimal data loading (fallback)
async function loadMinimalData() { async function loadMinimalData() {
//console.log('Loading minimal data...');
apps = []; apps = [];
categories = []; categories = [];
@ -645,11 +622,9 @@ async function loadMinimalData() {
// Preload essential data for smooth navigation // Preload essential data for smooth navigation
async function preloadOtherPagesData(currentPage) { async function preloadOtherPagesData(currentPage) {
//console.log('Preloading essential data for navigation...');
try { try {
// No preloading needed - data loads fresh each page // No preloading needed - data loads fresh each page
//console.log('Preloading complete (no caching)');
} catch (error) { } catch (error) {
console.error('Error preloading navigation data:', error); console.error('Error preloading navigation data:', error);

View File

@ -3,7 +3,6 @@
function safeGetElement(id) { function safeGetElement(id) {
const element = document.getElementById(id); const element = document.getElementById(id);
if (!element) { if (!element) {
//console.log(`${id} element not found`);
} }
return element; return element;
} }
@ -11,7 +10,6 @@ function safeGetElement(id) {
function safeQuerySelector(selector) { function safeQuerySelector(selector) {
const element = document.querySelector(selector); const element = document.querySelector(selector);
if (!element) { if (!element) {
//console.log(`${selector} element not found`);
} }
return element; return element;
} }
@ -19,7 +17,6 @@ function safeQuerySelector(selector) {
function safeQuerySelectorAll(selector) { function safeQuerySelectorAll(selector) {
const elements = document.querySelectorAll(selector); const elements = document.querySelectorAll(selector);
if (!elements || elements.length === 0) { if (!elements || elements.length === 0) {
//console.log(`${selector} elements not found`);
} }
return elements; return elements;
} }

View File

@ -11,7 +11,6 @@ class LibrePortalSPAClean {
} }
async init() { async init() {
//console.log('🚀 Clean SPA: Initializing...');
// Setup routes from the feature manifest (falls back to the built-in table) // Setup routes from the feature manifest (falls back to the built-in table)
await this.setupRoutesFromManifest(); await this.setupRoutesFromManifest();
@ -32,11 +31,9 @@ class LibrePortalSPAClean {
// Handle initial route // Handle initial route
this.handleInitialRoute(); this.handleInitialRoute();
//console.log('✅ Clean SPA: Initialization complete');
} }
async waitForTopbar() { async waitForTopbar() {
//console.log('⏳ Waiting for topbar to load...');
// Wait for topbar component to be available and loaded // Wait for topbar component to be available and loaded
let attempts = 0; let attempts = 0;
@ -46,7 +43,6 @@ class LibrePortalSPAClean {
if (typeof TopbarComponent !== 'undefined' && TopbarComponent.loadTopbar) { if (typeof TopbarComponent !== 'undefined' && TopbarComponent.loadTopbar) {
try { try {
await TopbarComponent.loadTopbar(); await TopbarComponent.loadTopbar();
//console.log('✅ Topbar loaded successfully');
return; return;
} catch (error) { } catch (error) {
console.warn('⚠️ Topbar loading failed, retrying...', error); console.warn('⚠️ Topbar loading failed, retrying...', error);
@ -78,7 +74,6 @@ class LibrePortalSPAClean {
// Legacy /config, /peers, /ssh are handled by _legacyRedirect() at the top // Legacy /config, /peers, /ssh are handled by _legacyRedirect() at the top
// of navigate() (rewrites to the canonical /admin/* path). // of navigate() (rewrites to the canonical /admin/* path).
//console.log('📍 Routes registered:', Array.from(this.routes.keys()));
} }
// Build the route table from the feature manifest (window.LP.features) so // Build the route table from the feature manifest (window.LP.features) so
@ -136,7 +131,6 @@ class LibrePortalSPAClean {
} }
} }
this._routesFromManifest = true; this._routesFromManifest = true;
//console.log('📍 Routes registered from manifest:', Array.from(this.routes.keys()));
} catch (err) { } catch (err) {
console.error('[spa] manifest routing failed, using built-in routes:', err); console.error('[spa] manifest routing failed, using built-in routes:', err);
this.setupRoutes(); this.setupRoutes();
@ -176,14 +170,12 @@ class LibrePortalSPAClean {
} }
async loadCoreData() { async loadCoreData() {
//console.log('📊 Loading core data...');
try { try {
// Load apps // Load apps
if (typeof DataLoader !== 'undefined' && DataLoader.loadApps) { if (typeof DataLoader !== 'undefined' && DataLoader.loadApps) {
this.apps = await DataLoader.loadApps(); this.apps = await DataLoader.loadApps();
window.apps = this.apps; window.apps = this.apps;
//console.log(`📱 Loaded ${this.apps.length} apps`);
} }
// Load categories // Load categories
@ -191,11 +183,9 @@ class LibrePortalSPAClean {
this.categories = await DataLoader.loadCategories(); this.categories = await DataLoader.loadCategories();
window.categories = this.categories; window.categories = this.categories;
window.sidebarCategories = this.categories; // Ensure this is always available window.sidebarCategories = this.categories; // Ensure this is always available
//console.log(`📂 Loaded ${Object.keys(this.categories).length} categories`);
} }
this.dataLoaded = true; this.dataLoaded = true;
//console.log('✅ Core data loaded successfully');
} catch (error) { } catch (error) {
console.error('❌ Failed to load core data:', error); console.error('❌ Failed to load core data:', error);
@ -205,20 +195,16 @@ class LibrePortalSPAClean {
handleInitialRoute() { handleInitialRoute() {
const path = window.location.pathname + window.location.search; const path = window.location.pathname + window.location.search;
// console.log('🎯 SPA: Handling initial route:', path);
// Handle root path - redirect to dashboard // Handle root path - redirect to dashboard
if (path === '/' || path === '') { if (path === '/' || path === '') {
// console.log('🏠 SPA: Redirecting to dashboard');
this.navigate('/dashboard', false); this.navigate('/dashboard', false);
} else { } else {
// console.log('🔀 SPA: Navigating to:', path);
this.navigate(path, false); // Don't add to history for initial load this.navigate(path, false); // Don't add to history for initial load
} }
} }
async navigate(path, addToHistory = true) { async navigate(path, addToHistory = true) {
// console.log('🚀 SPA: navigate called with:', path, 'addToHistory:', addToHistory);
// Legacy URL redirects (the old /ssh, /peers, /config short URLs → the Admin // Legacy URL redirects (the old /ssh, /peers, /config short URLs → the Admin
// area). Rewritten here, at the top of navigate() and BEFORE the isLoading // area). Rewritten here, at the top of navigate() and BEFORE the isLoading
@ -233,12 +219,10 @@ class LibrePortalSPAClean {
} }
if (this.isLoading) { if (this.isLoading) {
// console.log('⏳ Navigation already in progress, ignoring:', path);
return; return;
} }
if (this.currentRoute === path && addToHistory) { if (this.currentRoute === path && addToHistory) {
//console.log('🔄 Same route, skipping navigation:', path);
return; return;
} }
@ -259,7 +243,6 @@ class LibrePortalSPAClean {
// navigation. See components/dashboard/index.js.) // navigation. See components/dashboard/index.js.)
this.isLoading = true; this.isLoading = true;
//console.log('🧭 Navigating to:', path);
try { try {
// Update browser history // Update browser history
@ -303,11 +286,9 @@ class LibrePortalSPAClean {
} }
findRouteHandler(path) { findRouteHandler(path) {
//console.log('🔍 Finding handler for path:', path);
// Exact match first // Exact match first
if (this.routes.has(path)) { if (this.routes.has(path)) {
//console.log('✅ Exact match found:', path);
return this.routes.get(path); return this.routes.get(path);
} }
@ -317,11 +298,9 @@ class LibrePortalSPAClean {
basePath = path.split('?')[0]; basePath = path.split('?')[0];
} }
//console.log('🔍 Checking base path:', basePath, 'for full path:', path);
// Check base path against routes // Check base path against routes
if (this.routes.has(basePath)) { if (this.routes.has(basePath)) {
//console.log('✅ Base path match found:', basePath);
return this.routes.get(basePath); return this.routes.get(basePath);
} }
@ -330,31 +309,22 @@ class LibrePortalSPAClean {
if (route.includes('*')) { if (route.includes('*')) {
const pattern = route.replace('*', ''); const pattern = route.replace('*', '');
if (basePath.startsWith(pattern)) { if (basePath.startsWith(pattern)) {
//console.log('✅ Wildcard match:', pattern, 'for base path:', basePath);
return handler; return handler;
} }
} }
} }
//console.log('❌ No handler found for:', path);
//console.log('❌ Base path:', basePath);
//console.log('❌ Available routes:', Array.from(this.routes.keys()));
return null; return null;
} }
async handleDashboard() { async handleDashboard() {
// console.log('🏠 SPA: Loading dashboard...');
try { try {
// console.log('📄 SPA: Fetching dashboard content...');
const html = await this.fetchContent('/components/dashboard/html/dashboard-content.html'); const html = await this.fetchContent('/components/dashboard/html/dashboard-content.html');
// console.log('📄 SPA: Dashboard content fetched, loading...');
this.loadContent(html, 'Dashboard'); this.loadContent(html, 'Dashboard');
// console.log('📄 SPA: Dashboard content loaded');
// Dashboard should already be initialized by SystemLoader // Dashboard should already be initialized by SystemLoader
if (typeof loadInstalledApps === 'function') { if (typeof loadInstalledApps === 'function') {
// console.log('📱 SPA: Loading installed apps...');
loadInstalledApps(); loadInstalledApps();
} }
} catch (error) { } catch (error) {
@ -404,7 +374,6 @@ class LibrePortalSPAClean {
} }
async handleApps() { async handleApps() {
//console.log('📱 Loading apps...');
// Category from the path (/apps/<category>), else legacy ?=<cat> / ?apps=. // Category from the path (/apps/<category>), else legacy ?=<cat> / ?apps=.
const seg = window.location.pathname.replace(/^\/apps\/?/, '').split('/')[0]; const seg = window.location.pathname.replace(/^\/apps\/?/, '').split('/')[0];
@ -422,19 +391,15 @@ class LibrePortalSPAClean {
try { try {
// Ensure unified layout is loaded (like the old SPA) // Ensure unified layout is loaded (like the old SPA)
if (!document.querySelector('.apps-layout')) { if (!document.querySelector('.apps-layout')) {
//console.log('📄 Loading apps layout HTML...');
const html = await this.fetchContent('/components/apps/core/html/apps-unified-layout.html'); const html = await this.fetchContent('/components/apps/core/html/apps-unified-layout.html');
this.loadContent(html, 'Applications'); this.loadContent(html, 'Applications');
} else { } else {
//console.log('📄 Apps layout already exists, skipping HTML load');
} }
// Apps manager should already be initialized by SystemLoader // Apps manager should already be initialized by SystemLoader
if (window.appsManager) { if (window.appsManager) {
//console.log('✅ AppsManager already initialized by SystemLoader');
await window.appsManager.initialize(); await window.appsManager.initialize();
//console.log('✅ Apps loaded successfully');
} else { } else {
console.error('AppsManager not available - SystemLoader should have initialized it'); console.error('AppsManager not available - SystemLoader should have initialized it');
throw new Error('AppsManager not initialized by SystemLoader'); throw new Error('AppsManager not initialized by SystemLoader');
@ -446,7 +411,6 @@ class LibrePortalSPAClean {
} }
async handleAppDetail() { async handleAppDetail() {
//console.log('🔍 Loading app detail...');
// Extract app name. Path-based /app/<name> first, then legacy ?app= / ?=name. // Extract app name. Path-based /app/<name> first, then legacy ?app= / ?=name.
const url = new URL(window.location); const url = new URL(window.location);
@ -467,7 +431,6 @@ class LibrePortalSPAClean {
} }
} }
//console.log('🔍 Parsed app name:', appName, 'from URL:', url.search);
if (!appName) { if (!appName) {
this.navigate('/apps', false); this.navigate('/apps', false);
@ -496,14 +459,12 @@ class LibrePortalSPAClean {
// AppTabbedManager should already be initialized by SystemLoader // AppTabbedManager should already be initialized by SystemLoader
if (window.appTabbedManager) { if (window.appTabbedManager) {
// console.log('✅ AppTabbedManager already initialized by SystemLoader');
await window.appTabbedManager.initialize(); await window.appTabbedManager.initialize();
} else { } else {
console.error('AppTabbedManager not available - SystemLoader should have initialized it'); console.error('AppTabbedManager not available - SystemLoader should have initialized it');
throw new Error('AppTabbedManager not initialized by SystemLoader'); throw new Error('AppTabbedManager not initialized by SystemLoader');
} }
//console.log('✅ App detail loaded:', appName);
} catch (error) { } catch (error) {
console.error('❌ App detail load error:', error); console.error('❌ App detail load error:', error);
this.showError('Failed to load application details'); this.showError('Failed to load application details');
@ -535,7 +496,6 @@ class LibrePortalSPAClean {
// Legacy /config and /config?=<x> → the path-based /admin equivalent. // Legacy /config and /config?=<x> → the path-based /admin equivalent.
async handleTasks() { async handleTasks() {
//console.log('📋 Loading tasks...');
try { try {
const html = await this.fetchContent('/components/tasks/html/tasks-content.html'); const html = await this.fetchContent('/components/tasks/html/tasks-content.html');
@ -543,7 +503,6 @@ class LibrePortalSPAClean {
// Tasks manager should already be initialized by SystemLoader // Tasks manager should already be initialized by SystemLoader
if (window.tasksManager) { if (window.tasksManager) {
//console.log('✅ TasksManager already initialized by SystemLoader');
await window.tasksManager.init(); await window.tasksManager.init();
} else { } else {
console.warn('⚠️ TasksManager not available yet, task functionality will be limited'); console.warn('⚠️ TasksManager not available yet, task functionality will be limited');
@ -557,7 +516,6 @@ class LibrePortalSPAClean {
} }
async fetchContent(url) { async fetchContent(url) {
//console.log('📥 Fetching:', url);
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`); throw new Error(`HTTP ${response.status}: ${response.statusText}`);
@ -595,7 +553,6 @@ class LibrePortalSPAClean {
} }
updateNavigation() { updateNavigation() {
//console.log('🔗 SPA: Using fallback navigation logic');
// Remove ALL active classes // Remove ALL active classes
document.querySelectorAll('.nav-item').forEach(item => { document.querySelectorAll('.nav-item').forEach(item => {
@ -622,7 +579,6 @@ class LibrePortalSPAClean {
activeId = 'nav-dashboard'; activeId = 'nav-dashboard';
} }
//console.log('🔗 SPA: Setting active nav:', activeId);
const activeElement = document.getElementById(activeId); const activeElement = document.getElementById(activeId);
if (activeElement) { if (activeElement) {
activeElement.classList.add('nav-active'); activeElement.classList.add('nav-active');
@ -693,7 +649,6 @@ window.appPartsFromPath = function (pathname) {
// Global navigation function for click handlers // Global navigation function for click handlers
window.navigateToRoute = function(href) { window.navigateToRoute = function(href) {
if (window.spaClean) { if (window.spaClean) {
//console.log('🔗 Converting href:', href);
// Convert href to clean path - handle various formats // Convert href to clean path - handle various formats
let route = href.replace('.html', '').replace('./', '').replace(/^\//, ''); let route = href.replace('.html', '').replace('./', '').replace(/^\//, '');
@ -713,7 +668,6 @@ window.navigateToRoute = function(href) {
route = '/' + route; route = '/' + route;
} }
//console.log('🎯 Final route:', route);
window.spaClean.navigate(route); window.spaClean.navigate(route);
} }
}; };

View File

@ -261,9 +261,6 @@ class LoadingUI {
// Show error message // Show error message
showError(errors) { showError(errors) {
// console.log('🔍 LoadingUI.showError called with errors:', errors.length);
// console.log('🔍 Existing error details elements:', document.querySelectorAll('.error-details').length);
// console.log('🔍 Call stack:', new Error().stack);
const actionsContainer = document.getElementById('loading-actions'); const actionsContainer = document.getElementById('loading-actions');
@ -379,7 +376,6 @@ class LoadingUI {
attachEventListeners() { attachEventListeners() {
if (this.retryButton) { if (this.retryButton) {
this.retryButton.addEventListener('click', () => { this.retryButton.addEventListener('click', () => {
// console.log('🔄 Retry button clicked - refreshing page');
window.location.reload(); window.location.reload();
}); });
} }

View File

@ -29,11 +29,9 @@ class ConfirmationDialog {
this.overlay.addEventListener('click', () => this.hide()); this.overlay.addEventListener('click', () => this.hide());
this.dialog.addEventListener('click', (e) => e.stopPropagation()); this.dialog.addEventListener('click', (e) => e.stopPropagation());
//console.log('Confirmation dialog initialized');
} }
show(title, message, onConfirm, confirmText = 'Confirm', cancelText = 'Cancel', confirmClass = 'primary', showDataLossCheckbox = false) { show(title, message, onConfirm, confirmText = 'Confirm', cancelText = 'Cancel', confirmClass = 'primary', showDataLossCheckbox = false) {
//console.log('Showing confirmation dialog');
this.callback = onConfirm; this.callback = onConfirm;
@ -67,8 +65,6 @@ class ConfirmationDialog {
this.overlay.classList.add('active'); this.overlay.classList.add('active');
// Debug: Check if class was added // Debug: Check if class was added
//console.log('Active class added:', this.overlay.className);
//console.log('Has active class:', this.overlay.classList.contains('active'));
// Handle checkbox if present // Handle checkbox if present
if (showDataLossCheckbox) { if (showDataLossCheckbox) {
@ -87,7 +83,6 @@ class ConfirmationDialog {
}; };
document.addEventListener('keydown', handleEscape); document.addEventListener('keydown', handleEscape);
//console.log('Confirmation dialog shown');
} }
updateConfirmButton(isChecked) { updateConfirmButton(isChecked) {
@ -111,7 +106,6 @@ class ConfirmationDialog {
} }
} }
//console.log('Confirmation dialog confirmed');
if (this.callback) { if (this.callback) {
this.callback(); this.callback();
} }
@ -119,13 +113,9 @@ class ConfirmationDialog {
} }
hide() { hide() {
//console.log('Hiding confirmation dialog');
//console.log('Before remove - classes:', this.overlay.className);
this.overlay.classList.remove('active'); this.overlay.classList.remove('active');
//console.log('After remove - classes:', this.overlay.className);
//console.log('Has active class after remove:', this.overlay.classList.contains('active'));
this.callback = null; this.callback = null;
} }

View File

@ -161,8 +161,6 @@ class TaskCommands {
const taskFileName = `${taskId}.json`; const taskFileName = `${taskId}.json`;
const taskFilePath = `tasks/queue/${taskFileName}`; const taskFilePath = `tasks/queue/${taskFileName}`;
// console.log('🔍 Creating task file:', taskFilePath);
// console.log('🔍 Task ID:', taskId);
const task = { const task = {
id: taskId, id: taskId,
@ -175,7 +173,6 @@ class TaskCommands {
updatedAt: new Date().toISOString() updatedAt: new Date().toISOString()
}; };
// console.log('🔍 Task object:', task);
const response = await fetch('/write-file', { const response = await fetch('/write-file', {
method: 'POST', method: 'POST',

View File

@ -1,18 +1,14 @@
// Preserve task parameter before SPA strips it // Preserve task parameter before SPA strips it
(function() { (function() {
// console.log('🔍 Task parameter preservation script loaded');
// Check current URL for task parameter // Check current URL for task parameter
const currentUrl = window.location.href; const currentUrl = window.location.href;
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const taskId = urlParams.get('task'); const taskId = urlParams.get('task');
// console.log('🔍 Current URL:', currentUrl);
// console.log('🔍 Task parameter detected:', taskId);
if (taskId) { if (taskId) {
// Store task parameter in sessionStorage // Store task parameter in sessionStorage
sessionStorage.setItem('pendingTaskId', taskId); sessionStorage.setItem('pendingTaskId', taskId);
// console.log('🔍 Stored task ID in sessionStorage:', taskId);
} }
})(); })();

View File

@ -16,7 +16,6 @@ class TaskRouter {
*/ */
async routeAction(action, params = {}) { async routeAction(action, params = {}) {
try { try {
//console.log(`🎯 Routing action: ${action}`, params);
switch (action) { switch (action) {
case 'install': case 'install':
@ -102,7 +101,6 @@ class TaskRouter {
}; };
this.commandQueue.push(queuedTask); this.commandQueue.push(queuedTask);
//console.log(`📋 Queued action: ${action}`, params);
// Start processing if not already running // Start processing if not already running
if (!this.isProcessing) { if (!this.isProcessing) {
@ -121,17 +119,14 @@ class TaskRouter {
} }
this.isProcessing = true; this.isProcessing = true;
//console.log('🔄 Processing command queue...');
while (this.commandQueue.length > 0) { while (this.commandQueue.length > 0) {
const queuedTask = this.commandQueue.shift(); const queuedTask = this.commandQueue.shift();
try { try {
//console.log(`⚡ Executing queued action: ${queuedTask.action}`);
await this.routeAction(queuedTask.action, queuedTask.params); await this.routeAction(queuedTask.action, queuedTask.params);
queuedTask.status = 'completed'; queuedTask.status = 'completed';
//console.log(`✅ Completed queued action: ${queuedTask.action}`);
} catch (error) { } catch (error) {
queuedTask.status = 'failed'; queuedTask.status = 'failed';
@ -158,7 +153,6 @@ class TaskRouter {
} }
this.isProcessing = false; this.isProcessing = false;
//console.log('✅ Command queue processing complete');
} }
/** /**

View File

@ -304,7 +304,6 @@ class TopbarComponent {
if (href) { if (href) {
// Special handling for tasks navigation // Special handling for tasks navigation
if (item.id === 'nav-tasks' && window.tasksManager) { if (item.id === 'nav-tasks' && window.tasksManager) {
// console.log('🔄 Tasks button clicked - forcing clean state and reloading...');
// Force clean state // Force clean state
window.tasksManager.highlightedTaskId = null; window.tasksManager.highlightedTaskId = null;