diff --git a/apps/web/src/dashboard/query-builder.js b/apps/web/src/dashboard/query-builder.js index 44354d0..9161475 100644 --- a/apps/web/src/dashboard/query-builder.js +++ b/apps/web/src/dashboard/query-builder.js @@ -205,7 +205,7 @@ class QueryBuilder { Query JSON -
${query ? escapeHtml(JSON.stringify(query, null, 2)) : 'No conditions set'}
+ ${query ? escapeHtml(formatQueryJson(query)) : 'No conditions set'}
`;
@@ -230,7 +230,7 @@ class QueryBuilder {
this.container.querySelector('#qb-copy').addEventListener('click', () => {
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');
btn.textContent = 'Copied!';
setTimeout(() => { btn.textContent = 'Copy'; }, 1500);
@@ -326,7 +326,43 @@ class QueryBuilder {
const q = this.getQuery();
const preview = this.container.querySelector('#qb-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(', ') + ' }';
+}