fixed some bugs
This commit is contained in:
parent
943915a242
commit
69bd604279
1 changed files with 343 additions and 348 deletions
81
dist/js/app.js
vendored
81
dist/js/app.js
vendored
|
|
@ -52,7 +52,7 @@ class ComponentLifecycle {
|
|||
onDestroy(fn) {
|
||||
if (this.#isDestroyed) {
|
||||
console.warn('Cannot register cleanup on destroyed component');
|
||||
return () => {};
|
||||
return () => { };
|
||||
}
|
||||
|
||||
this.#cleanupFns.push(fn);
|
||||
|
|
@ -143,7 +143,7 @@ class EventBus {
|
|||
emit(event, data) {
|
||||
const listeners = this.#events.get(event);
|
||||
if (listeners) {
|
||||
listeners.forEach(callback => {
|
||||
[...listeners].forEach(callback => {
|
||||
try {
|
||||
callback(data);
|
||||
} catch (error) {
|
||||
|
|
@ -161,8 +161,8 @@ class EventBus {
|
|||
*/
|
||||
once(event, callback) {
|
||||
const wrappedCallback = (data) => {
|
||||
callback(data);
|
||||
this.off(event, wrappedCallback);
|
||||
callback(data);
|
||||
};
|
||||
return this.on(event, wrappedCallback);
|
||||
}
|
||||
|
|
@ -368,7 +368,7 @@ const memoize = (fn, options = {}) => {
|
|||
const maxSize = options.maxSize || 100;
|
||||
const keyGenerator = options.keyGenerator || JSON.stringify;
|
||||
|
||||
const memoized = function(...args) {
|
||||
const memoized = function (...args) {
|
||||
const key = keyGenerator(args);
|
||||
|
||||
if (cache.has(key)) {
|
||||
|
|
@ -401,16 +401,12 @@ const Utils = (() => {
|
|||
const debounceCache = new WeakMap();
|
||||
|
||||
const debounce = (func, wait = CONFIG.PERFORMANCE.DEBOUNCE_DELAY) => {
|
||||
if (debounceCache.has(func)) return debounceCache.get(func);
|
||||
|
||||
let timeoutId;
|
||||
const debounced = function executeDebouncedFunction(...args) {
|
||||
const debounced = function (...args) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
|
||||
debounced.cancel = () => clearTimeout(timeoutId);
|
||||
debounceCache.set(func, debounced);
|
||||
return debounced;
|
||||
};
|
||||
|
||||
|
|
@ -831,7 +827,7 @@ class FocusManager {
|
|||
'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"]):not([disabled])'
|
||||
);
|
||||
|
||||
if (focusable.length === 0) return () => {};
|
||||
if (focusable.length === 0) return () => { };
|
||||
|
||||
const first = focusable[0];
|
||||
const last = focusable[focusable.length - 1];
|
||||
|
|
@ -901,7 +897,7 @@ class KeyboardNavigation {
|
|||
static setupTableNavigation(table) {
|
||||
let currentRow = -1;
|
||||
const tbody = table.querySelector('tbody');
|
||||
if (!tbody) return () => {};
|
||||
if (!tbody) return () => { };
|
||||
|
||||
const getRows = () => Array.from(tbody.querySelectorAll('tr:not(.empty-state-row)'));
|
||||
|
||||
|
|
@ -963,7 +959,7 @@ class ResponsiveTable {
|
|||
*/
|
||||
static makeResponsive(table) {
|
||||
const wrapper = table.closest('.table-wrapper');
|
||||
if (!wrapper) return () => {};
|
||||
if (!wrapper) return () => { };
|
||||
|
||||
const checkResponsive = () => {
|
||||
const isMobile = window.innerWidth < 768;
|
||||
|
|
@ -1302,8 +1298,9 @@ class TableManager {
|
|||
});
|
||||
|
||||
// Create header
|
||||
|
||||
const thead = Utils.createElement('thead');
|
||||
thead.innerHTML = this.#generateHeaderHTML(columns);
|
||||
thead.appendChild(this.#generateHeaderRow(columns));
|
||||
table.appendChild(thead);
|
||||
|
||||
// Create body
|
||||
|
|
@ -1328,31 +1325,35 @@ class TableManager {
|
|||
this.#renderTableBody();
|
||||
}
|
||||
|
||||
#generateHeaderHTML(columns) {
|
||||
const generateHeaderCell = (label, dataColumn) => `
|
||||
<th class="sortable"
|
||||
data-column="${dataColumn}"
|
||||
tabindex="0"
|
||||
role="columnheader"
|
||||
aria-sort="none">
|
||||
<span>${label}</span>
|
||||
<svg class="sort-icon" width="12" height="12" viewBox="0 0 24 24"
|
||||
fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
|
||||
<path d="M12 5v14M5 12l7-7 7 7"/>
|
||||
</svg>
|
||||
</th>
|
||||
`;
|
||||
#generateHeaderRow(columns) {
|
||||
const row = Utils.createElement('tr');
|
||||
|
||||
const columnHeaders = columns
|
||||
.map(col => generateHeaderCell(col, col))
|
||||
.join('');
|
||||
const makeHeaderCell = (label, dataColumn) => {
|
||||
const th = Utils.createElement('th', {
|
||||
className: 'sortable',
|
||||
tabindex: '0',
|
||||
role: 'columnheader',
|
||||
'aria-sort': 'none',
|
||||
dataset: { column: dataColumn }
|
||||
});
|
||||
const span = Utils.createElement('span', {}, [label]); // text node — safe
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
svg.setAttribute('width', '12'); svg.setAttribute('height', '12');
|
||||
svg.setAttribute('viewBox', '0 0 24 24'); svg.setAttribute('fill', 'none');
|
||||
svg.setAttribute('stroke', 'currentColor'); svg.setAttribute('stroke-width', '2');
|
||||
svg.setAttribute('aria-hidden', 'true');
|
||||
svg.classList.add('sort-icon');
|
||||
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||||
path.setAttribute('d', 'M12 5v14M5 12l7-7 7 7');
|
||||
svg.appendChild(path);
|
||||
th.appendChild(span);
|
||||
th.appendChild(svg);
|
||||
return th;
|
||||
};
|
||||
|
||||
return `
|
||||
<tr>
|
||||
${generateHeaderCell('Service Name', 'service')}
|
||||
${columnHeaders}
|
||||
</tr>
|
||||
`;
|
||||
row.appendChild(makeHeaderCell('Service Name', 'service'));
|
||||
columns.forEach(col => row.appendChild(makeHeaderCell(col, col)));
|
||||
return row;
|
||||
}
|
||||
|
||||
#renderTableBody() {
|
||||
|
|
@ -1478,20 +1479,14 @@ class TableManager {
|
|||
}
|
||||
|
||||
#loadAllEntries() {
|
||||
// Update state to show all entries
|
||||
this.#state.update({ isFullyLoaded: true });
|
||||
|
||||
// Show loading indicator on button
|
||||
const btn = this.#elements.loadAllBtn?.querySelector('.load-all-btn');
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = `
|
||||
<div class="loading-spinner" style="width: 20px; height: 20px; margin-right: 8px;"></div>
|
||||
Loading...
|
||||
`;
|
||||
btn.innerHTML = `<div class="loading-spinner" style="width:20px;height:20px;margin-right:8px;"></div>Loading...`;
|
||||
}
|
||||
|
||||
// Re-render table body with all entries
|
||||
setTimeout(() => {
|
||||
this.#removeLoadAllButton();
|
||||
this.#renderTableBody();
|
||||
|
|
|
|||
Loading…
Reference in a new issue