diff --git a/odex25_base/fims_general_search_tree_view/static/src/js/list_search.js b/odex25_base/fims_general_search_tree_view/static/src/js/list_search.js index 14c8ba4f2..3c03eab67 100644 --- a/odex25_base/fims_general_search_tree_view/static/src/js/list_search.js +++ b/odex25_base/fims_general_search_tree_view/static/src/js/list_search.js @@ -30,9 +30,9 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { _renderView: function () { var self = this; - // Store search state before render + // PREVENT INFINITE LOOP: Don't re-trigger search during render var searchValue = this._search ? this._search.value : ''; - var hasActiveSearch = searchValue && searchValue.length > 0; + var isCurrentlySearching = this._search && this._search.isFiltered; return this._super.apply(this, arguments).then(function () { // Add search box if needed @@ -47,10 +47,11 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { // Always restore search UI self._restoreSearchUI(); - // If we had an active search, re-apply it after a short delay - if (hasActiveSearch) { + // CRITICAL FIX: Only re-apply search if it's a manual page load, NOT during search operations + if (searchValue && !isCurrentlySearching && !self._searchInProgress) { + console.log('Re-applying search after page load:', searchValue); setTimeout(function() { - if (self._search && self._search.value) { + if (self._search && self._search.value && !self._searchInProgress) { self._performSearch(self._search.value); } }, 100); @@ -71,7 +72,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { '' + '' + '' + - '' + + '' + ''; this.$el.prepend($(html)); }, @@ -92,6 +93,8 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { isFiltered: false, lastSearchPromise: null }; + // Add flag to prevent infinite loops + this._searchInProgress = false; } }, @@ -161,24 +164,38 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { }, /** - * Perform search - THE MAIN SEARCH LOGIC + * Perform search - ENHANCED WITH LOOP PREVENTION */ _performSearch: function(value) { var self = this; + // PREVENT INFINITE LOOPS + if (this._searchInProgress) { + console.log('Search already in progress, ignoring'); + return Promise.resolve(); + } + // Use mutex to prevent concurrent searches return this._searchMutex.exec(function() { + // Set flag to prevent loops + self._searchInProgress = true; + // Clear if empty if (!value) { - return self._clearSearch(); + return self._clearSearch().finally(function() { + self._searchInProgress = false; + }); } // Check prerequisites if (!self.state || !self.state.model) { console.error('Missing model information'); - return; + self._searchInProgress = false; + return Promise.resolve(); } + console.log('=== Starting search for:', value, '==='); + // Store original data on first search if (!self._search.originalData && !self._search.isFiltered) { self._storeOriginalData(); @@ -227,6 +244,9 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { } }).finally(function() { self._showLoading(false); + // CRITICAL: Clear the progress flag + self._searchInProgress = false; + console.log('=== Search completed ==='); }); }); }, @@ -237,6 +257,8 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { _processSearchResults: function(records) { var count = records.length; + console.log('Processing search results:', count, 'records'); + // Update search state this._search.isFiltered = true; this._search.allFilteredRecords = records; @@ -247,8 +269,8 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { if (count === 0) { this._showNoResults(); - // CRITICAL: Update main pager for empty results - this._forceUpdateMainPager(0); + // Update main pager for empty results - WITHOUT RELOAD + this._updatePagerOnly(0); return; } @@ -257,22 +279,20 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { }, /** - * Update view with filtered data - FIXED CRITICAL LOGIC + * Update view with filtered data - ENHANCED TO PREVENT LOOPS */ _updateViewWithFilteredData: function(records) { console.log('=== _updateViewWithFilteredData ==='); console.log('Records count:', records.length); console.log('Filtered IDs:', this._search.filteredIds); - // ALWAYS try to update the view, regardless of DOM filtering success - // Method 1: Try DOM filtering first (fastest if it works) var domFilterWorked = this._filterExistingRows(); console.log('DOM filtering worked:', domFilterWorked); if (domFilterWorked) { - // DOM filtering worked, but STILL update pager properly - this._forceUpdateMainPager(records.length); + // DOM filtering worked, update pager WITHOUT causing reload + this._updatePagerOnly(records.length); return; } @@ -300,7 +320,6 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { console.log('=== DOM Filtering Debug ==='); console.log('Total rows in DOM:', $allRows.length); console.log('Looking for IDs:', this._search.filteredIds); - console.log('Limit:', limit); // First, collect all available row IDs for debugging $allRows.each(function(index) { @@ -339,13 +358,11 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { visibleCount++; foundAnyMatch = true; console.log('✓ Showing row', index, 'with ID', rowId); - } else { - console.log('✗ Hiding row', index, 'with ID', rowId, '(over limit)'); } } }); - console.log('DOM filtering completed - Visible rows:', visibleCount, 'Found matches:', foundAnyMatch); + console.log('DOM filtering completed - Visible rows:', visibleCount); return foundAnyMatch && visibleCount > 0; }, @@ -381,21 +398,21 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { this._showNoResults(); } - // CRITICAL: Force update main pager - this._forceUpdateMainPager(records.length); + // Update pager WITHOUT causing reload + this._updatePagerOnly(records.length); }, /** - * CRITICAL FIX: Force update main Odoo pager + * SAFE PAGER UPDATE - WITHOUT RELOAD TRIGGERS */ - _forceUpdateMainPager: function(totalCount) { - console.log('=== Updating Main Pager ==='); + _updatePagerOnly: function(totalCount) { + console.log('=== Safe Pager Update ==='); console.log('Total count:', totalCount); - // Method 1: Try standard pager update - if (this.getParent() && this.getParent().pager) { + // Method 1: Try standard pager update (SAFEST - no reload) + if (this.getParent() && this.getParent().pager && this.getParent().pager.updateState) { try { - console.log('Trying method 1: getParent().pager.updateState'); + console.log('Trying method 1: safe pager updateState'); this.getParent().pager.updateState({ current_min: totalCount > 0 ? 1 : 0, size: totalCount, @@ -408,13 +425,13 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { } } - // Method 2: Try alternative pager access + // Method 2: Try alternative pager access (SAFE) try { var controller = this.getParent(); while (controller && !controller.pager) { controller = controller.getParent(); } - if (controller && controller.pager) { + if (controller && controller.pager && controller.pager.updateState) { console.log('Trying method 2: controller.pager'); controller.pager.updateState({ current_min: totalCount > 0 ? 1 : 0, @@ -428,30 +445,14 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { console.warn('Method 2 failed:', err); } - // Method 3: Direct state update + trigger change + // Method 3: Direct DOM update (SAFEST FALLBACK - no triggers) try { - console.log('Trying method 3: direct state update'); - if (this.state) { - this.state.count = totalCount; - // Trigger a state change event - this.trigger_up('reload', { - keepChanges: true, - currentId: this.state.res_id - }); - console.log('✓ Method 3 triggered'); - } - } catch (err) { - console.warn('Method 3 failed:', err); - } - - // Method 4: Update DOM directly if all else fails - try { - console.log('Trying method 4: direct DOM update'); + console.log('Trying method 3: direct DOM update'); var $pager = this.$el.closest('.o_content').find('.o_pager_value'); if ($pager.length) { var displayText = totalCount > 0 ? '1-' + Math.min(totalCount, this.state.limit || 80) : '0'; $pager.text(displayText); - console.log('✓ Method 4 succeeded'); + console.log('✓ Method 3 succeeded - updated pager value'); } var $pagerSize = this.$el.closest('.o_content').find('.o_pager_size'); @@ -459,9 +460,26 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { $pagerSize.text(totalCount); console.log('✓ Updated pager size directly'); } + + // Also try standard pager selectors + var $standardPager = $('.o_pager_value'); + if ($standardPager.length) { + var displayText = totalCount > 0 ? '1-' + Math.min(totalCount, this.state.limit || 80) : '0'; + $standardPager.text(displayText); + console.log('✓ Updated standard pager'); + } + + var $standardSize = $('.o_pager_size'); + if ($standardSize.length) { + $standardSize.text(totalCount); + console.log('✓ Updated standard pager size'); + } } catch (err) { - console.warn('Method 4 failed:', err); + console.warn('Method 3 failed:', err); } + + // REMOVED: Method that caused infinite loop (trigger_up reload) + console.log('Pager update completed'); }, /** @@ -658,18 +676,27 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { this._showNoResults(); } - // CRITICAL: Update main pager - this._forceUpdateMainPager(visible); + // Update pager safely + this._updatePagerOnly(visible); console.log('Client-side search completed. Visible:', visible, 'IDs:', matchedIds); }, /** - * Clear search - ENHANCED + * Clear search - ENHANCED WITH LOOP PREVENTION */ _clearSearch: function() { console.log('=== Clearing search ==='); + // PREVENT LOOPS during clear + if (this._searchInProgress) { + console.log('Search in progress during clear, setting flag to clear after'); + this._pendingClear = true; + return Promise.resolve(); + } + + this._searchInProgress = true; + // Clear UI this.$('.oe_search_input').val(''); this.$('.oe_clear_search').hide(); @@ -683,6 +710,8 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { this._search.isFiltered = false; this._search.lastSearchPromise = null; + var promise; + // Restore original data if (this._search.originalData) { console.log('Restoring original data:', this._search.originalData); @@ -705,12 +734,14 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { $(this).toggle(index < limit); }); - // CRITICAL: Restore main pager - this._forceUpdateMainPager(this._search.originalData.count); + // Restore pager safely + this._updatePagerOnly(this._search.originalData.count); // Clear stored original data this._search.originalData = null; this._search.originalDomain = null; + + promise = Promise.resolve(); } else { // Just show all rows with limit var $rows = this.$('.o_data_row'); @@ -724,11 +755,17 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) { }); if (this.state) { - this._forceUpdateMainPager(this.state.count || $rows.length); + this._updatePagerOnly(this.state.count || $rows.length); } + + promise = Promise.resolve(); } + // Clear flags + this._searchInProgress = false; console.log('Search cleared successfully'); + + return promise; }, /**