Refactor Alpine.js components: remove memory cleanup code from requests, fix keyboard event handling in validation
This commit is contained in:
parent
79e6ab63a0
commit
e947fc74d4
@ -112,9 +112,6 @@ document.addEventListener('alpine:init', () => {
|
|||||||
this.totalPages = Math.ceil(this.filtered.length / this.pageSize) || 1;
|
this.totalPages = Math.ceil(this.filtered.length / this.pageSize) || 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Track timeouts for cleanup
|
|
||||||
toastTimeouts: [],
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.today = new Date().toISOString().slice(0, 10);
|
this.today = new Date().toISOString().slice(0, 10);
|
||||||
this.filter.date1 = this.today;
|
this.filter.date1 = this.today;
|
||||||
@ -123,58 +120,36 @@ document.addEventListener('alpine:init', () => {
|
|||||||
const defaultPrinter = '<?= $config[session()->get("userrole")]["sampleDialog"]["defaultPrinter"] ?? "lab" ?>';
|
const defaultPrinter = '<?= $config[session()->get("userrole")]["sampleDialog"]["defaultPrinter"] ?? "lab" ?>';
|
||||||
this.selectedPrinter = defaultPrinter || 'lab';
|
this.selectedPrinter = defaultPrinter || 'lab';
|
||||||
|
|
||||||
// Single consolidated watcher for list changes
|
// Watchers for reactive updates
|
||||||
this.$watch('list', () => {
|
this.$watch('list', () => {
|
||||||
this.computeFiltered();
|
this.computeFiltered();
|
||||||
this.computeValidatedCount();
|
this.computeValidatedCount();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Single watcher for filter changes
|
|
||||||
this.$watch('filterKey', () => this.computeFiltered());
|
this.$watch('filterKey', () => this.computeFiltered());
|
||||||
this.$watch('filterTable', () => {
|
this.$watch('filterTable', () => {
|
||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
this.computeFiltered();
|
this.computeFiltered();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Single watcher for computed chain
|
|
||||||
this.$watch('filtered', () => {
|
this.$watch('filtered', () => {
|
||||||
this.computeSorted();
|
this.computeSorted();
|
||||||
this.computeTotalPages();
|
this.computeTotalPages();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort changes trigger pagination update
|
|
||||||
this.$watch('sortCol', () => this.computeSorted());
|
this.$watch('sortCol', () => this.computeSorted());
|
||||||
this.$watch('sortAsc', () => this.computeSorted());
|
this.$watch('sortAsc', () => this.computeSorted());
|
||||||
this.$watch('sorted', () => this.computePaginated());
|
this.$watch('sorted', () => this.computePaginated());
|
||||||
this.$watch('currentPage', () => this.computePaginated());
|
this.$watch('currentPage', () => this.computePaginated());
|
||||||
|
|
||||||
// Watch audit data changes to recompute events
|
|
||||||
this.$watch('auditData', () => {
|
this.$watch('auditData', () => {
|
||||||
this.computeAuditEvents();
|
this.computeAuditEvents();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register cleanup on destroy
|
// Initial load only - no auto-refresh
|
||||||
this.$cleanup(() => this.destroy());
|
|
||||||
|
|
||||||
this.fetchList();
|
this.fetchList();
|
||||||
},
|
},
|
||||||
|
|
||||||
// Cleanup method to prevent memory leaks
|
|
||||||
destroy() {
|
|
||||||
// Clear all tracked timeouts
|
|
||||||
this.toastTimeouts.forEach(id => clearTimeout(id));
|
|
||||||
this.toastTimeouts = [];
|
|
||||||
|
|
||||||
// Clear large data structures
|
|
||||||
this.list = [];
|
|
||||||
this.filtered = [];
|
|
||||||
this.sorted = [];
|
|
||||||
this.paginated = [];
|
|
||||||
this.auditData = null;
|
|
||||||
this.item = null;
|
|
||||||
this.previewItem = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
fetchList() {
|
fetchList() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this.list = [];
|
this.list = [];
|
||||||
@ -557,13 +532,7 @@ document.addEventListener('alpine:init', () => {
|
|||||||
toast.className = `alert alert-${type} fixed top-4 right-4 z-50`;
|
toast.className = `alert alert-${type} fixed top-4 right-4 z-50`;
|
||||||
toast.innerHTML = `<i class="fa ${type === 'error' ? 'fa-times-circle' : 'fa-check-circle'}"></i> ${message}`;
|
toast.innerHTML = `<i class="fa ${type === 'error' ? 'fa-times-circle' : 'fa-check-circle'}"></i> ${message}`;
|
||||||
document.body.appendChild(toast);
|
document.body.appendChild(toast);
|
||||||
const timeoutId = setTimeout(() => {
|
setTimeout(() => toast.remove(), 2000);
|
||||||
toast.remove();
|
|
||||||
// Remove from tracking array
|
|
||||||
const idx = this.toastTimeouts.indexOf(timeoutId);
|
|
||||||
if (idx > -1) this.toastTimeouts.splice(idx, 1);
|
|
||||||
}, 2000);
|
|
||||||
this.toastTimeouts.push(timeoutId);
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|||||||
@ -86,7 +86,7 @@ document.addEventListener('alpine:init', () => {
|
|||||||
this.currentPage = 1;
|
this.currentPage = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set up watchers to update cached computed properties
|
// Watchers for reactive updates
|
||||||
this.$watch('unvalidatedList', () => {
|
this.$watch('unvalidatedList', () => {
|
||||||
this.computeUnvalidatedFiltered();
|
this.computeUnvalidatedFiltered();
|
||||||
this.computeUnvalidatedCount();
|
this.computeUnvalidatedCount();
|
||||||
@ -111,13 +111,12 @@ document.addEventListener('alpine:init', () => {
|
|||||||
this.computeUnvalidatedPaginated();
|
this.computeUnvalidatedPaginated();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Auto-fetch on page load
|
// Initial load only - no auto-refresh
|
||||||
this.fetchUnvalidated();
|
this.fetchUnvalidated();
|
||||||
|
|
||||||
// Keyboard shortcuts for dialog
|
// Keyboard shortcuts - added/removed when dialog opens/closes
|
||||||
document.addEventListener('keydown', (e) => {
|
this._keyboardHandler = (e) => {
|
||||||
if (this.isDialogValOpen) {
|
if (this.isDialogValOpen) {
|
||||||
// N key - skip to next
|
|
||||||
if (e.key === 'n' || e.key === 'N') {
|
if (e.key === 'n' || e.key === 'N') {
|
||||||
if (!e.target.closest('input, textarea, button')) {
|
if (!e.target.closest('input, textarea, button')) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -125,7 +124,8 @@ document.addEventListener('alpine:init', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
document.addEventListener('keydown', this._keyboardHandler);
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchUnvalidated() {
|
fetchUnvalidated() {
|
||||||
@ -198,6 +198,10 @@ document.addEventListener('alpine:init', () => {
|
|||||||
this.valAccessnumber = item.SP_ACCESSNUMBER;
|
this.valAccessnumber = item.SP_ACCESSNUMBER;
|
||||||
this.valItem = item;
|
this.valItem = item;
|
||||||
this.isDialogValOpen = true;
|
this.isDialogValOpen = true;
|
||||||
|
// Re-add keyboard handler when dialog opens
|
||||||
|
if (this._keyboardHandler) {
|
||||||
|
document.addEventListener('keydown', this._keyboardHandler);
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const btn = document.getElementById('validate-btn');
|
const btn = document.getElementById('validate-btn');
|
||||||
if (btn) btn.focus();
|
if (btn) btn.focus();
|
||||||
@ -225,6 +229,11 @@ document.addEventListener('alpine:init', () => {
|
|||||||
}
|
}
|
||||||
this.validationDelayRemaining = 0;
|
this.validationDelayRemaining = 0;
|
||||||
this.isIframeLoaded = false;
|
this.isIframeLoaded = false;
|
||||||
|
// Remove keyboard handler when dialog closes
|
||||||
|
if (this._keyboardHandler) {
|
||||||
|
document.removeEventListener('keydown', this._keyboardHandler);
|
||||||
|
this._keyboardHandler = null;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
skipToNext() {
|
skipToNext() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user