|
2463
|
2463
|
.debug-controls { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; width: 100%; }
|
|
2464
|
2464
|
.debug-meta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
2465
|
2465
|
.debug-table-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px; padding: 10px; border-top: 1px solid var(--line); }
|
|
2466
|
|
- .debug-table-card { display: grid; align-content: center; justify-items: start; gap: 5px; min-height: 58px; padding: 9px 10px; text-align: left; background: #fff; }
|
|
|
2466
|
+ .debug-table-card { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 6px; min-height: 58px; padding: 8px; border: 1px solid var(--line); border-radius: 6px; background: #fff; }
|
|
2467
|
2467
|
.debug-table-card:hover { border-color: #9fb7e9; background: #f8fbff; }
|
|
2468
|
2468
|
.debug-table-card.active { border-color: var(--accent); background: #e8f0fe; box-shadow: inset 0 0 0 1px var(--accent); }
|
|
|
2469
|
+ .debug-table-card-main { display: grid; align-content: center; justify-items: start; gap: 5px; min-width: 0; min-height: 42px; width: 100%; padding: 4px 6px; border: 0; background: transparent; text-align: left; }
|
|
|
2470
|
+ .debug-table-card-main:hover { background: transparent; }
|
|
2469
|
2471
|
.debug-table-card-name { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); font-weight: 700; }
|
|
2470
|
2472
|
.debug-table-card-rows { color: var(--muted); font-size: 12px; }
|
|
|
2473
|
+ .debug-table-copy { min-width: 34px; width: 34px; justify-content: center; padding: 7px; color: var(--muted); }
|
|
2471
|
2474
|
.debug-section { display: grid; gap: 16px; }
|
|
2472
|
2475
|
.host-tools { display: flex; align-items: center; justify-content: flex-end; gap: 8px; min-width: 0; }
|
|
2473
|
2476
|
.host-tools input { max-width: 240px; }
|
|
3012
|
3015
|
['rows', data.counts ? data.counts.rows : tables.reduce((total, table) => total + Number(table.rows || 0), 0)],
|
|
3013
|
3016
|
].map(([k, v]) => `<span class="stat">${escapeHtml(k)}: ${escapeHtml(String(v))}</span>`).join('');
|
|
3014
|
3017
|
$('debug-db-meta').textContent = data.database || '';
|
|
3015
|
|
- renderDebugTableCards(tables, selected);
|
|
|
3018
|
+ renderDebugTableCards(tables, selected, data.database || '');
|
|
3016
|
3019
|
if (selected) {
|
|
3017
|
3020
|
await renderDebugTable(selected);
|
|
3018
|
3021
|
} else {
|
|
3020
|
3023
|
}
|
|
3021
|
3024
|
}
|
|
3022
|
3025
|
|
|
3023
|
|
- function renderDebugTableCards(tables, selected) {
|
|
|
3026
|
+ function renderDebugTableCards(tables, selected, database) {
|
|
3024
|
3027
|
$('debug-db-tables').innerHTML = tables.length
|
|
3025
|
3028
|
? tables.map(table => {
|
|
3026
|
3029
|
const active = table.name === selected;
|
|
3027
|
|
- return `<button type="button" class="debug-table-card ${active ? 'active' : ''}" data-debug-table="${escapeHtml(table.name)}" aria-pressed="${active ? 'true' : 'false'}">
|
|
3028
|
|
- <span class="debug-table-card-name mono">${escapeHtml(table.name)}</span>
|
|
3029
|
|
- <span class="debug-table-card-rows">${escapeHtml(String(table.rows || 0))} rows</span>
|
|
3030
|
|
- </button>`;
|
|
|
3030
|
+ const ref = debugTableReference(database, table.name);
|
|
|
3031
|
+ return `<div class="debug-table-card ${active ? 'active' : ''}">
|
|
|
3032
|
+ <button type="button" class="debug-table-card-main" data-debug-table="${escapeHtml(table.name)}" aria-pressed="${active ? 'true' : 'false'}">
|
|
|
3033
|
+ <span class="debug-table-card-name mono">${escapeHtml(table.name)}</span>
|
|
|
3034
|
+ <span class="debug-table-card-rows">${escapeHtml(String(table.rows || 0))} rows</span>
|
|
|
3035
|
+ </button>
|
|
|
3036
|
+ <button type="button" class="debug-table-copy" data-debug-table-ref="${escapeHtml(ref)}" title="${escapeHtml(ref)}" aria-label="Copy full table reference for ${escapeHtml(table.name)}">Ref</button>
|
|
|
3037
|
+ </div>`;
|
|
3031
|
3038
|
}).join('')
|
|
3032
|
3039
|
: '<div class="ca-empty muted">No database tables found.</div>';
|
|
3033
|
3040
|
document.querySelectorAll('[data-debug-table]').forEach(button => {
|
|
3035
|
3042
|
if (!isAuthLost(e)) msg(e.message);
|
|
3036
|
3043
|
}));
|
|
3037
|
3044
|
});
|
|
|
3045
|
+ document.querySelectorAll('[data-debug-table-ref]').forEach(button => {
|
|
|
3046
|
+ button.addEventListener('click', async () => {
|
|
|
3047
|
+ try {
|
|
|
3048
|
+ await copyText(button.dataset.debugTableRef || '');
|
|
|
3049
|
+ msg('table reference copied');
|
|
|
3050
|
+ } catch (e) {
|
|
|
3051
|
+ msg('copy failed');
|
|
|
3052
|
+ }
|
|
|
3053
|
+ });
|
|
|
3054
|
+ });
|
|
|
3055
|
+ }
|
|
|
3056
|
+
|
|
|
3057
|
+ function debugTableReference(database, tableName) {
|
|
|
3058
|
+ return `sqlite:${database || ''}#${tableName || ''}`;
|
|
3038
|
3059
|
}
|
|
3039
|
3060
|
|
|
3040
|
3061
|
async function selectDebugTable(tableName) {
|
|
3041
|
3062
|
state.debugTable = tableName || '';
|
|
3042
|
3063
|
document.querySelectorAll('[data-debug-table]').forEach(button => {
|
|
3043
|
3064
|
const active = button.dataset.debugTable === state.debugTable;
|
|
3044
|
|
- button.classList.toggle('active', active);
|
|
|
3065
|
+ const card = button.closest('.debug-table-card');
|
|
|
3066
|
+ if (card) card.classList.toggle('active', active);
|
|
3045
|
3067
|
button.setAttribute('aria-pressed', active ? 'true' : 'false');
|
|
3046
|
3068
|
});
|
|
3047
|
3069
|
if (state.debugTable) await renderDebugTable(state.debugTable);
|