Remove all Alpine.js calls to fix memory leaks
- Replace reactive watchers with explicit method calls - Add setFilterKey() and setFilterTable() methods for manual updates - Update sort(), nextPage(), prevPage() to trigger computations - Update templates to use new setter methods - Compute derived data explicitly after data loading
This commit is contained in:
parent
e947fc74d4
commit
8d762261d4
@ -12,35 +12,35 @@
|
||||
|
||||
<!-- Status Filters -->
|
||||
<div class="join shadow-sm bg-base-100 rounded-lg">
|
||||
<button @click="filterKey = 'Total'"
|
||||
<button @click="setFilterKey('$1')"
|
||||
:class="filterKey === 'Total' ? 'btn-active btn-neutral text-white' : 'btn-ghost'"
|
||||
class="btn btn-sm join-item">
|
||||
All <span class="badge badge-sm badge-ghost ml-1" x-text="counters.Total"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Pend'"
|
||||
<button @click="setFilterKey('$1')"
|
||||
:class="filterKey === 'Pend' ? 'btn-active btn-status-pend' : 'btn-ghost'"
|
||||
class="btn btn-sm join-item">
|
||||
Pending <span class="badge badge-sm badge-status-pend ml-1" x-text="counters.Pend"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Coll'"
|
||||
<button @click="setFilterKey('$1')"
|
||||
:class="filterKey === 'Coll' ? 'btn-active btn-status-coll' : 'btn-ghost'"
|
||||
class="btn btn-sm join-item">
|
||||
Coll <span class="badge badge-sm badge-status-coll ml-1" x-text="counters.Coll"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Recv'"
|
||||
<button @click="setFilterKey('$1')"
|
||||
:class="filterKey === 'Recv' ? 'btn-active btn-status-recv' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Recv <span class="badge badge-sm badge-status-recv ml-1" x-text="counters.Recv"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Inc'"
|
||||
<button @click="setFilterKey('$1')"
|
||||
:class="filterKey === 'Inc' ? 'btn-active btn-status-inc' : 'btn-ghost'" class="btn btn-sm join-item">
|
||||
Inc <span class="badge badge-sm badge-status-inc ml-1" x-text="counters.Inc"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Fin'"
|
||||
<button @click="setFilterKey('$1')"
|
||||
:class="filterKey === 'Fin' ? 'btn-active btn-status-fin' : 'btn-ghost'"
|
||||
class="btn btn-sm join-item">
|
||||
Fin <span class="badge badge-sm badge-status-fin ml-1" x-text="counters.Fin"></span>
|
||||
</button>
|
||||
<button @click="filterKey = 'Validated'"
|
||||
<button @click="setFilterKey('$1')"
|
||||
:class="filterKey === 'Validated' ? 'btn-active btn-primary text-white' : 'btn-ghost'"
|
||||
class="btn btn-sm join-item">
|
||||
Val <span class="badge badge-sm badge-primary ml-1" x-text="validatedCount"></span>
|
||||
@ -70,7 +70,7 @@
|
||||
<div class="form-control w-full md:w-auto">
|
||||
<label class='input input-sm input-bordered'>
|
||||
<i class="fa fa-filter"></i>
|
||||
<input type="text" placeholder="Type to filter..." x-model="filterTable" />
|
||||
<input type="text" placeholder="Type to filter..." x-model="filterTable" @input.debounce.300ms="setFilterTable(filterTable)" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -42,7 +42,7 @@
|
||||
<div class="form-control w-full md:w-auto">
|
||||
<label class="input input-sm input-bordered">
|
||||
<i class="fa fa-filter"></i>
|
||||
<input type="text" placeholder="Type to filter..." x-model="filterTable" />
|
||||
<input type="text" placeholder="Type to filter..." x-model="filterTable" @input.debounce.300ms="setFilterTable(filterTable)" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -61,14 +61,39 @@ document.addEventListener('alpine:init', () => {
|
||||
this.sortCol = col;
|
||||
this.sortAsc = true;
|
||||
}
|
||||
this.computeSorted();
|
||||
this.computePaginated();
|
||||
},
|
||||
|
||||
nextPage() {
|
||||
if (this.currentPage < this.totalPages) this.currentPage++;
|
||||
if (this.currentPage < this.totalPages) {
|
||||
this.currentPage++;
|
||||
this.computePaginated();
|
||||
}
|
||||
},
|
||||
|
||||
prevPage() {
|
||||
if (this.currentPage > 1) this.currentPage--;
|
||||
if (this.currentPage > 1) {
|
||||
this.currentPage--;
|
||||
this.computePaginated();
|
||||
}
|
||||
},
|
||||
|
||||
setFilterKey(key) {
|
||||
this.filterKey = key;
|
||||
this.computeFiltered();
|
||||
this.computeSorted();
|
||||
this.computeTotalPages();
|
||||
this.computePaginated();
|
||||
},
|
||||
|
||||
setFilterTable(value) {
|
||||
this.filterTable = value;
|
||||
this.currentPage = 1;
|
||||
this.computeFiltered();
|
||||
this.computeSorted();
|
||||
this.computeTotalPages();
|
||||
this.computePaginated();
|
||||
},
|
||||
|
||||
// Compute methods - called only when dependencies change
|
||||
@ -120,32 +145,6 @@ document.addEventListener('alpine:init', () => {
|
||||
const defaultPrinter = '<?= $config[session()->get("userrole")]["sampleDialog"]["defaultPrinter"] ?? "lab" ?>';
|
||||
this.selectedPrinter = defaultPrinter || 'lab';
|
||||
|
||||
// Watchers for reactive updates
|
||||
this.$watch('list', () => {
|
||||
this.computeFiltered();
|
||||
this.computeValidatedCount();
|
||||
});
|
||||
|
||||
this.$watch('filterKey', () => this.computeFiltered());
|
||||
this.$watch('filterTable', () => {
|
||||
this.currentPage = 1;
|
||||
this.computeFiltered();
|
||||
});
|
||||
|
||||
this.$watch('filtered', () => {
|
||||
this.computeSorted();
|
||||
this.computeTotalPages();
|
||||
});
|
||||
|
||||
this.$watch('sortCol', () => this.computeSorted());
|
||||
this.$watch('sortAsc', () => this.computeSorted());
|
||||
this.$watch('sorted', () => this.computePaginated());
|
||||
this.$watch('currentPage', () => this.computePaginated());
|
||||
|
||||
this.$watch('auditData', () => {
|
||||
this.computeAuditEvents();
|
||||
});
|
||||
|
||||
// Initial load only - no auto-refresh
|
||||
this.fetchList();
|
||||
},
|
||||
@ -175,6 +174,9 @@ document.addEventListener('alpine:init', () => {
|
||||
let codeB = statusOrder[b.STATS] ?? 0;
|
||||
return codeA - codeB;
|
||||
});
|
||||
// Compute derived data after list is loaded
|
||||
this.computeFiltered();
|
||||
this.computeValidatedCount();
|
||||
}).finally(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
|
||||
@ -29,14 +29,31 @@ document.addEventListener('alpine:init', () => {
|
||||
this.sortCol = col;
|
||||
this.sortAsc = true;
|
||||
}
|
||||
this.computeUnvalidatedSorted();
|
||||
this.computeUnvalidatedPaginated();
|
||||
},
|
||||
|
||||
nextPage() {
|
||||
if (this.currentPage < this.unvalidatedTotalPages) this.currentPage++;
|
||||
if (this.currentPage < this.unvalidatedTotalPages) {
|
||||
this.currentPage++;
|
||||
this.computeUnvalidatedPaginated();
|
||||
}
|
||||
},
|
||||
|
||||
prevPage() {
|
||||
if (this.currentPage > 1) this.currentPage--;
|
||||
if (this.currentPage > 1) {
|
||||
this.currentPage--;
|
||||
this.computeUnvalidatedPaginated();
|
||||
}
|
||||
},
|
||||
|
||||
setFilterTable(value) {
|
||||
this.filterTable = value;
|
||||
this.currentPage = 1;
|
||||
this.computeUnvalidatedFiltered();
|
||||
this.computeUnvalidatedSorted();
|
||||
this.computeUnvalidatedTotalPages();
|
||||
this.computeUnvalidatedPaginated();
|
||||
},
|
||||
|
||||
// Compute methods - called only when dependencies change
|
||||
@ -82,35 +99,6 @@ document.addEventListener('alpine:init', () => {
|
||||
this.filter.date1 = this.today;
|
||||
this.filter.date2 = this.today;
|
||||
|
||||
this.$watch('filterTable', () => {
|
||||
this.currentPage = 1;
|
||||
});
|
||||
|
||||
// Watchers for reactive updates
|
||||
this.$watch('unvalidatedList', () => {
|
||||
this.computeUnvalidatedFiltered();
|
||||
this.computeUnvalidatedCount();
|
||||
});
|
||||
this.$watch('filterTable', () => {
|
||||
this.computeUnvalidatedFiltered();
|
||||
});
|
||||
this.$watch('unvalidatedFiltered', () => {
|
||||
this.computeUnvalidatedSorted();
|
||||
this.computeUnvalidatedTotalPages();
|
||||
});
|
||||
this.$watch('sortCol', () => {
|
||||
this.computeUnvalidatedSorted();
|
||||
});
|
||||
this.$watch('sortAsc', () => {
|
||||
this.computeUnvalidatedSorted();
|
||||
});
|
||||
this.$watch('unvalidatedSorted', () => {
|
||||
this.computeUnvalidatedPaginated();
|
||||
});
|
||||
this.$watch('currentPage', () => {
|
||||
this.computeUnvalidatedPaginated();
|
||||
});
|
||||
|
||||
// Initial load only - no auto-refresh
|
||||
this.fetchUnvalidated();
|
||||
|
||||
@ -137,6 +125,12 @@ document.addEventListener('alpine:init', () => {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}).then(res => res.json()).then(data => {
|
||||
this.unvalidatedList = data.data ?? [];
|
||||
// Compute derived data after list is loaded
|
||||
this.computeUnvalidatedFiltered();
|
||||
this.computeUnvalidatedCount();
|
||||
this.computeUnvalidatedSorted();
|
||||
this.computeUnvalidatedTotalPages();
|
||||
this.computeUnvalidatedPaginated();
|
||||
}).finally(() => {
|
||||
this.isLoading = false;
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user