improve query presentation
This commit is contained in:
parent
7da67364c4
commit
a415dab320
|
|
@ -205,7 +205,7 @@ class QueryBuilder {
|
||||||
<span class="text-xs text-gray-500 font-mono">Query JSON</span>
|
<span class="text-xs text-gray-500 font-mono">Query JSON</span>
|
||||||
<button id="qb-copy" class="text-xs text-blue-400 hover:text-blue-300">Copy</button>
|
<button id="qb-copy" class="text-xs text-blue-400 hover:text-blue-300">Copy</button>
|
||||||
</div>
|
</div>
|
||||||
<pre id="qb-preview" class="text-xs text-gray-300 font-mono whitespace-pre-wrap overflow-x-auto">${query ? escapeHtml(JSON.stringify(query, null, 2)) : '<span class="text-gray-600">No conditions set</span>'}</pre>
|
<pre id="qb-preview" class="text-xs text-gray-300 font-mono whitespace-pre-wrap overflow-x-auto">${query ? escapeHtml(formatQueryJson(query)) : '<span class="text-gray-600">No conditions set</span>'}</pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
@ -230,7 +230,7 @@ class QueryBuilder {
|
||||||
|
|
||||||
this.container.querySelector('#qb-copy').addEventListener('click', () => {
|
this.container.querySelector('#qb-copy').addEventListener('click', () => {
|
||||||
const q = this.getQuery();
|
const q = this.getQuery();
|
||||||
navigator.clipboard.writeText(q ? JSON.stringify(q, null, 2) : '{}');
|
navigator.clipboard.writeText(q ? formatQueryJson(q) : '{}');
|
||||||
const btn = this.container.querySelector('#qb-copy');
|
const btn = this.container.querySelector('#qb-copy');
|
||||||
btn.textContent = 'Copied!';
|
btn.textContent = 'Copied!';
|
||||||
setTimeout(() => { btn.textContent = 'Copy'; }, 1500);
|
setTimeout(() => { btn.textContent = 'Copy'; }, 1500);
|
||||||
|
|
@ -326,7 +326,43 @@ class QueryBuilder {
|
||||||
const q = this.getQuery();
|
const q = this.getQuery();
|
||||||
const preview = this.container.querySelector('#qb-preview');
|
const preview = this.container.querySelector('#qb-preview');
|
||||||
if (preview) {
|
if (preview) {
|
||||||
preview.textContent = q ? JSON.stringify(q, null, 2) : 'No conditions set';
|
preview.textContent = q ? formatQueryJson(q) : 'No conditions set';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compact-but-readable JSON formatter. Inlines any subtree that fits on a single
|
||||||
|
// line within MAX_INLINE chars; otherwise breaks across lines with 2-space indent.
|
||||||
|
const MAX_INLINE = 60;
|
||||||
|
|
||||||
|
function formatQueryJson(value, indent = 0) {
|
||||||
|
const inline = inlineForm(value);
|
||||||
|
if (inline.length + indent <= MAX_INLINE) return inline;
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (value.length === 0) return '[]';
|
||||||
|
const pad = ' '.repeat(indent + 2);
|
||||||
|
const close = ' '.repeat(indent);
|
||||||
|
const items = value.map(v => pad + formatQueryJson(v, indent + 2));
|
||||||
|
return '[\n' + items.join(',\n') + '\n' + close + ']';
|
||||||
|
}
|
||||||
|
if (value && typeof value === 'object') {
|
||||||
|
const entries = Object.entries(value);
|
||||||
|
if (entries.length === 0) return '{}';
|
||||||
|
const pad = ' '.repeat(indent + 2);
|
||||||
|
const close = ' '.repeat(indent);
|
||||||
|
const items = entries.map(([k, v]) => pad + JSON.stringify(k) + ': ' + formatQueryJson(v, indent + 2 + JSON.stringify(k).length + 2));
|
||||||
|
return '{\n' + items.join(',\n') + '\n' + close + '}';
|
||||||
|
}
|
||||||
|
return JSON.stringify(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function inlineForm(value) {
|
||||||
|
if (value === null || typeof value !== 'object') return JSON.stringify(value);
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (value.length === 0) return '[]';
|
||||||
|
return '[ ' + value.map(inlineForm).join(', ') + ' ]';
|
||||||
|
}
|
||||||
|
const entries = Object.entries(value);
|
||||||
|
if (entries.length === 0) return '{}';
|
||||||
|
return '{ ' + entries.map(([k, v]) => JSON.stringify(k) + ': ' + inlineForm(v)).join(', ') + ' }';
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue