(modelsData)
| 9100 | await window.performCombinedSearch(); |
| 9101 | } |
| 9102 | } |
| 9103 | }, 300); // Delay to ensure database write completes |
| 9104 | } |
| 9105 | }); |
| 9106 | |
| 9107 | // Force grid to refetch and re-render (Docker/server: performCombinedSearch alone often doesn't update the grid) |
| 9108 | async function forceGridRefresh() { |
| 9109 | window.disableGridRefresh = false; |
| 9110 | const gridEl = document.querySelector('.file-grid'); |
| 9111 | if (gridEl) gridEl.currentModels = null; // force renderVirtualGrid to treat as changed and re-render |
| 9112 | if (typeof populateFileTypeFilter === 'function') await populateFileTypeFilter(); |
| 9113 | const sortSelect = document.getElementById('sort-select'); |
| 9114 | const sortOption = sortSelect ? sortSelect.value : 'date-desc'; |
| 9115 | try { |
| 9116 | const models = await window.electron.getAllModels(sortOption, 0); |
| 9117 | if (typeof renderFiles === 'function') await renderFiles(models); |
| 9118 | } catch (err) { |
| 9119 | console.error('[forceGridRefresh]', err); |
| 9120 | } |
| 9121 | } |
| 9122 | window.forceGridRefresh = forceGridRefresh; |
| 9123 | |
| 9124 | window.electron.onRefreshGrid(async () => { |
| 9125 | // Always allow grid refresh when server/main signals (e.g. after scan in docker/server mode) |
| 9126 | window.disableGridRefresh = false; |
| 9127 | const gridEl = document.querySelector('.file-grid'); |
| 9128 | if (gridEl) gridEl.currentModels = null; |
| 9129 | if (typeof populateFileTypeFilter === 'function') await populateFileTypeFilter(); |
| 9130 | // Preserve dateAddedFilter if it's set |
| 9131 | const preservedDateAddedFilter = window.dateAddedFilter || window._lastDateAddedFilter; |
| 9132 | if (preservedDateAddedFilter) { |
| 9133 | console.log('onRefreshGrid called, preserving dateAddedFilter:', preservedDateAddedFilter); |
| 9134 | window.dateAddedFilter = preservedDateAddedFilter; |
| 9135 | window._lastDateAddedFilter = preservedDateAddedFilter; |
| 9136 | } |
| 9137 | selectedModels.clear(); |
| 9138 | document.querySelectorAll('.file-item.selected').forEach(item => item.classList.remove('selected')); |
| 9139 | |
| 9140 | // Match search.js: any active filter must reload via performCombinedSearch — forceGridRefresh uses |
| 9141 | // getAllModels() and would drop search/tag/etc. (e.g. after "Remove from Library" while filtered). |
| 9142 | const designer = document.getElementById('designer-select')?.value || ''; |
| 9143 | const license = document.getElementById('license-select')?.value || ''; |
| 9144 | const parentModel = document.getElementById('parent-select')?.value || ''; |
| 9145 | const printStatus = document.getElementById('printed-select')?.value || 'all'; |
| 9146 | const newStatus = document.getElementById('new-select')?.value || 'all'; |
| 9147 | const tagFilter = document.getElementById('tag-filter')?.value || ''; |
| 9148 | const fileType = document.getElementById('filetype-select')?.value || ''; |
| 9149 | const searchTerm = (document.getElementById('search-filter-input')?.value || '').trim(); |
| 9150 | const qbClauses = |
| 9151 | typeof window.queryBuilderHasActiveSearchClauses === 'function' && |
| 9152 | window.queryBuilderHasActiveSearchClauses(); |
| 9153 | const qbMulti = |
| 9154 | typeof window.queryBuilderHasActiveMultiFilters === 'function' && |
| 9155 | window.queryBuilderHasActiveMultiFilters(); |
| 9156 | const hasActiveFilters = Boolean( |
| 9157 | designer || license || parentModel || printStatus !== 'all' || |
| 9158 | newStatus !== 'all' || |
| 9159 | tagFilter || fileType || searchTerm || qbClauses || qbMulti || |
no test coverage detected