admindb 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/LICENSE +20 -20
  2. package/dist/app.js +36 -25
  3. package/dist/core/context.d.ts +1 -0
  4. package/dist/core/context.js +2 -0
  5. package/dist/core/errors.d.ts +1 -0
  6. package/dist/core/errors.js +39 -0
  7. package/dist/core/index.d.ts +1 -0
  8. package/dist/core/index.js +20 -0
  9. package/dist/core/result.d.ts +1 -0
  10. package/dist/core/result.js +10 -0
  11. package/dist/core/router.d.ts +1 -0
  12. package/dist/core/router.js +37 -0
  13. package/dist/data/chain.js +1 -1
  14. package/dist/data/engine.js +1 -1
  15. package/dist/db/database.d.ts +1 -1
  16. package/dist/db/database.js +9 -31
  17. package/dist/db/dialects/index.d.ts +1 -0
  18. package/dist/db/dialects/index.js +58 -0
  19. package/dist/db/dialects/postgres/ddl.d.ts +1 -0
  20. package/dist/db/dialects/postgres/ddl.js +107 -0
  21. package/dist/db/dialects/postgres/dialect.d.ts +1 -0
  22. package/dist/db/dialects/postgres/dialect.js +28 -0
  23. package/dist/db/dialects/postgres/introspector.d.ts +1 -0
  24. package/dist/db/dialects/postgres/introspector.js +265 -0
  25. package/dist/db/dialects/postgres/types.d.ts +1 -0
  26. package/dist/db/dialects/postgres/types.js +83 -0
  27. package/dist/db/dialects/sqlite/ddl.d.ts +1 -0
  28. package/dist/db/dialects/sqlite/ddl.js +244 -0
  29. package/dist/db/dialects/sqlite/dialect.d.ts +1 -0
  30. package/dist/db/dialects/sqlite/dialect.js +25 -0
  31. package/dist/db/dialects/sqlite/introspector.d.ts +1 -0
  32. package/dist/db/dialects/sqlite/introspector.js +214 -0
  33. package/dist/db/dialects/sqlite/types.d.ts +1 -0
  34. package/dist/db/dialects/sqlite/types.js +69 -0
  35. package/dist/db/dialects/types.d.ts +1 -0
  36. package/dist/db/dialects/types.js +15 -0
  37. package/dist/db/export.js +1 -1
  38. package/dist/db/index.d.ts +1 -1
  39. package/dist/db/index.js +1 -1
  40. package/dist/db/manager.d.ts +1 -1
  41. package/dist/db/manager.js +101 -21
  42. package/dist/db/postgres.d.ts +1 -1
  43. package/dist/db/postgres.js +20 -284
  44. package/dist/db/types.d.ts +1 -1
  45. package/dist/db/types.js +0 -4
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.js +4 -1
  48. package/dist/modules/databases/databases.routes.d.ts +1 -0
  49. package/dist/modules/databases/databases.routes.js +150 -0
  50. package/dist/modules/databases/databases.service.d.ts +1 -0
  51. package/dist/modules/databases/databases.service.js +134 -0
  52. package/dist/modules/databases/index.d.ts +1 -0
  53. package/dist/{routes → modules/databases}/index.js +2 -3
  54. package/dist/modules/erd/erd.routes.d.ts +1 -0
  55. package/dist/modules/erd/erd.routes.js +32 -0
  56. package/dist/modules/erd/erd.service.d.ts +1 -0
  57. package/dist/modules/erd/erd.service.js +39 -0
  58. package/dist/modules/erd/index.d.ts +1 -0
  59. package/dist/modules/erd/index.js +18 -0
  60. package/dist/modules/index.d.ts +1 -0
  61. package/dist/modules/index.js +62 -0
  62. package/dist/modules/query/index.d.ts +1 -0
  63. package/dist/modules/query/index.js +18 -0
  64. package/dist/modules/query/query.routes.d.ts +1 -0
  65. package/dist/modules/query/query.routes.js +54 -0
  66. package/dist/modules/query/query.service.d.ts +1 -0
  67. package/dist/modules/query/query.service.js +95 -0
  68. package/dist/modules/rows/blob.helper.d.ts +1 -0
  69. package/dist/modules/rows/blob.helper.js +40 -0
  70. package/dist/modules/rows/display.helper.d.ts +1 -0
  71. package/dist/modules/rows/display.helper.js +73 -0
  72. package/dist/modules/rows/index.d.ts +1 -0
  73. package/dist/modules/rows/index.js +20 -0
  74. package/dist/modules/rows/rows.routes.d.ts +1 -0
  75. package/dist/modules/rows/rows.routes.js +555 -0
  76. package/dist/modules/rows/rows.service.d.ts +1 -0
  77. package/dist/modules/rows/rows.service.js +433 -0
  78. package/dist/modules/schema/index.d.ts +1 -0
  79. package/dist/modules/schema/index.js +18 -0
  80. package/dist/modules/schema/schema.routes.d.ts +1 -0
  81. package/dist/modules/schema/schema.routes.js +171 -0
  82. package/dist/modules/schema/schema.service.d.ts +1 -0
  83. package/dist/modules/schema/schema.service.js +58 -0
  84. package/dist/modules/seed/index.d.ts +1 -0
  85. package/dist/modules/seed/index.js +18 -0
  86. package/dist/modules/seed/seed.routes.d.ts +1 -0
  87. package/dist/modules/seed/seed.routes.js +212 -0
  88. package/dist/modules/seed/seed.service.d.ts +1 -0
  89. package/dist/{routes/api/helpers.js → modules/seed/seed.service.js} +86 -109
  90. package/dist/modules/tables/index.d.ts +1 -0
  91. package/dist/modules/tables/index.js +18 -0
  92. package/dist/modules/tables/tables.routes.d.ts +1 -0
  93. package/dist/modules/tables/tables.routes.js +194 -0
  94. package/dist/modules/tables/tables.service.d.ts +1 -0
  95. package/dist/modules/tables/tables.service.js +218 -0
  96. package/dist/public/js/browse.js +1 -1
  97. package/dist/public/js/query.js +1 -1
  98. package/dist/types/api.d.ts +1 -1
  99. package/dist/utils/common.d.ts +1 -1
  100. package/dist/utils/common.js +1 -3
  101. package/dist/utils/stream.d.ts +1 -0
  102. package/dist/utils/stream.js +131 -0
  103. package/dist/views/pages/error.hbs +10 -1
  104. package/dist/views/pages/home.hbs +1 -1
  105. package/dist/views/pages/query.hbs +1 -1
  106. package/dist/views/pages/seed-select.hbs +1 -252
  107. package/dist/views/pages/seed.hbs +1 -307
  108. package/dist/views/pages/table.hbs +1 -1
  109. package/dist/views/partials/sidebar.hbs +1 -1
  110. package/docs/API.md +4 -17
  111. package/docs/EXAMPLES.md +579 -579
  112. package/docs/SECURITY.md +265 -265
  113. package/package.json +4 -2
  114. package/dist/db/introspection.d.ts +0 -1
  115. package/dist/db/introspection.js +0 -164
  116. package/dist/routes/api/erd.d.ts +0 -1
  117. package/dist/routes/api/erd.js +0 -45
  118. package/dist/routes/api/helpers.d.ts +0 -1
  119. package/dist/routes/api/import-export.d.ts +0 -1
  120. package/dist/routes/api/import-export.js +0 -84
  121. package/dist/routes/api/index.d.ts +0 -1
  122. package/dist/routes/api/index.js +0 -55
  123. package/dist/routes/api/query.d.ts +0 -1
  124. package/dist/routes/api/query.js +0 -77
  125. package/dist/routes/api/rows.d.ts +0 -1
  126. package/dist/routes/api/rows.js +0 -373
  127. package/dist/routes/api/seed.d.ts +0 -1
  128. package/dist/routes/api/seed.js +0 -180
  129. package/dist/routes/api/tables.d.ts +0 -1
  130. package/dist/routes/api/tables.js +0 -230
  131. package/dist/routes/databases.d.ts +0 -1
  132. package/dist/routes/databases.js +0 -212
  133. package/dist/routes/index.d.ts +0 -1
  134. package/dist/routes/pages.d.ts +0 -1
  135. package/dist/routes/pages.js +0 -540
@@ -1 +1 @@
1
- <div class="space-y-6">
2
1
  <div class="page-header">
3
2
  <div class="page-header-row">
4
3
  <div>
5
4
  <div class="page-pretitle">Workspace</div>
6
5
  <h1 class="page-title">Query editor</h1>
7
6
  <p class="mt-0.5 text-xs text-base-content/60">Run arbitrary SQL — SELECT results render as a table, COUNT gives a summary, and write statements execute.</p>
8
7
  </div>
9
8
  <div class="page-actions">
10
9
  {{#unless readonly}}
11
10
  <button id="save-query" type="button" class="btn btn-outline btn-sm gap-1.5">
12
11
  {{{icon "save" class="h-4 w-4"}}}
13
12
  Save query
14
13
  </button>
15
14
  {{/unless}}
16
15
  <button id="run-query" type="button" class="btn btn-primary btn-sm gap-1.5">
17
16
  {{{icon "run" class="h-4 w-4"}}}
18
17
  Run query
19
18
  </button>
20
19
  </div>
21
20
  </div>
22
21
  </div>
23
22
  <div class="flex flex-wrap items-end gap-3">
24
23
  <div class="form-control w-full max-w-xs">
25
24
  <label class="field-label" for="saved-query-select">Saved queries</label>
26
25
  <select id="saved-query-select" class="field-select">
27
26
  <option value="">— select a saved query —</option>
28
27
  {{#each savedQueries}}
29
28
  <option value="{{this.id}}">{{this.name}}</option>
30
29
  {{/each}}
31
30
  </select>
32
31
  </div>
33
32
  {{#unless readonly}}
34
33
  <button id="delete-query" type="button" class="btn btn-ghost btn-sm mb-0.5 text-error" disabled>Delete saved</button>
35
34
  <div class="form-control w-full max-w-xs">
36
35
  <label class="field-label" for="save-query-name">Save current SQL as</label>
37
36
  <div class="join w-full">
38
37
  <input id="save-query-name" type="text" class="field-input join-item !rounded-r-none" placeholder="query name" autocomplete="off" />
39
38
  <button id="save-query-inline" type="button" class="btn btn-outline join-item">Save</button>
40
39
  </div>
41
40
  </div>
42
41
  {{/unless}}
43
42
  </div>
44
43
  <div class="app-card overflow-hidden">
45
44
  <div class="flex flex-wrap items-center justify-between gap-2 border-b border-base-200 bg-base-200/40 px-4 py-2">
46
45
  <div class="flex items-center gap-2">
47
46
  <span class="flex items-center gap-1.5 text-xs font-semibold text-base-content/70">
48
47
  <span class="grid h-5 w-5 place-items-center rounded bg-primary/10 text-primary">
49
48
  {{{icon "query" class="h-3.5 w-3.5"}}}
50
49
  </span>
51
50
  query.sql
52
51
  </span>
53
52
  <span class="badge badge-sm badge-ghost font-mono text-[10px] uppercase font-bold">{{#if isPostgres}}Postgres{{else}}SQLite{{/if}}</span>
54
53
  </div>
55
54
  <div class="flex flex-wrap items-center gap-1.5">
56
55
  <div class="dropdown dropdown-end">
57
56
  <label tabindex="0" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
58
57
  {{{icon "terminal" class="h-3.5 w-3.5"}}}
59
58
  Snippets
60
59
  </label>
61
60
  <ul tabindex="0" class="dropdown-content z-30 menu p-1.5 shadow-2xl bg-base-100 rounded-xl w-56 border border-base-300 text-xs">
62
61
  <li class="menu-title text-[10px] uppercase tracking-wider text-base-content/40">Query Templates</li>
63
62
  <li><a class="js-snippet" data-snippet="SELECT * FROM table_name\nWHERE condition\nORDER BY id DESC\nLIMIT 50;">SELECT rows</a></li>
64
63
  <li><a class="js-snippet" data-snippet="SELECT COUNT(*) AS total\nFROM table_name;">COUNT summary</a></li>
65
64
  <li><a class="js-snippet" data-snippet="SELECT a.*, b.*\nFROM table_a a\nJOIN table_b b ON b.a_id = a.id\nLIMIT 50;">JOIN tables</a></li>
66
65
  <li><a class="js-snippet" data-snippet="INSERT INTO table_name (col1, col2)\nVALUES ('value1', 'value2');">INSERT row</a></li>
67
66
  <li><a class="js-snippet" data-snippet="UPDATE table_name\nSET col1 = 'value1'\nWHERE id = 1;">UPDATE row</a></li>
68
67
  <li><a class="js-snippet" data-snippet="DELETE FROM table_name\nWHERE id = 1;">DELETE row</a></li>
69
68
  <li><a class="js-snippet" data-snippet="CREATE TABLE new_table (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n);">CREATE TABLE</a></li>
70
69
  </ul>
71
70
  </div>
72
71
  <button id="format-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" title="Format SQL (Beautify)">
73
72
  {{{icon "format" class="h-3.5 w-3.5"}}}
74
73
  Format
75
74
  </button>
76
75
  <button id="copy-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" title="Copy SQL to clipboard">
77
76
  {{{icon "copy" class="h-3.5 w-3.5"}}}
78
77
  Copy
79
78
  </button>
80
79
  <button id="clear-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-error" title="Clear editor">
81
80
  {{{icon "trash" class="h-3.5 w-3.5"}}}
82
81
  Clear
83
82
  </button>
84
83
  <span class="hidden sm:inline-block text-[11px] text-base-content/35 border-l border-base-300 pl-2">Ctrl/⌘ + Enter to run</span>
85
84
  </div>
86
85
  </div>
87
86
  <div class="sql-editor-wrap">
88
87
  <div id="query-gutter" class="sql-gutter" aria-hidden="true">
89
88
  <div class="sql-gutter-line">1</div>
90
89
  </div>
91
90
  <div class="sql-editor-stage">
92
91
  <pre id="query-highlight" class="sql-code-highlight" aria-hidden="true"><code id="query-code"></code></pre>
93
92
  <textarea id="query-sql" class="sql-code-input" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" placeholder="-- Write SQL here or choose a snippet/saved query&#10;SELECT * FROM table_name WHERE …"></textarea>
94
93
  </div>
95
94
  </div>
96
95
  <div class="flex items-center justify-between border-t border-base-200 bg-base-200/30 px-3.5 py-1.5 text-[11px] font-mono text-base-content/50">
97
96
  <div class="flex items-center gap-3">
98
97
  <span id="editor-cursor-pos">Ln 1, Col 1</span>
99
98
  <span id="editor-stats">0 chars</span>
100
99
  </div>
101
100
  <div class="flex items-center gap-2">
102
101
  <span class="text-[10px] text-base-content/40">Tab to indent · Ctrl+Z / Ctrl+Y to undo/redo · Ctrl+/ to comment</span>
103
102
  </div>
104
103
  </div>
105
104
  <div id="query-message" class="p-3"></div>
106
105
  </div>
107
106
  <div id="query-result" class="hidden">
108
107
  <div class="app-card overflow-hidden">
109
108
  <div class="flex items-center gap-2 border-b border-base-200 px-4 py-3">
110
109
  <span id="result-kind" class="grid h-6 w-6 place-items-center rounded-md bg-success/10 text-success">
111
110
  {{{icon "check" class="h-4 w-4"}}}
112
111
  </span>
113
112
  <span id="result-summary" class="text-sm font-medium text-base-content/60"></span>
114
113
  <div class="ml-auto flex items-center gap-1.5">
115
114
  <button id="export-csv" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" disabled>
116
115
  {{{icon "export" class="h-3.5 w-3.5"}}}
117
116
  CSV
118
117
  </button>
119
118
  <button id="export-json" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" disabled>
120
119
  {{{icon "export" class="h-3.5 w-3.5"}}}
121
120
  JSON
122
121
  </button>
123
122
  </div>
124
123
  </div>
125
124
  <div class="overflow-x-auto">
126
125
  <table class="table table-sm table-pin-rows">
127
126
  <thead id="query-result-head" class="bg-base-200/70 text-xs uppercase tracking-wide text-base-content/50"></thead>
128
127
  <tbody id="query-result-body"></tbody>
129
128
  </table>
130
129
  </div>
131
130
  </div>
132
131
  </div>
132
+ <div class="space-y-6">
133
133
  <div class="page-header">
134
134
  <div class="page-header-row">
135
135
  <div>
136
136
  <div class="page-pretitle">Workspace</div>
137
137
  <h1 class="page-title">Query editor</h1>
138
138
  <p class="mt-0.5 text-xs text-base-content/60">Run arbitrary SQL — SELECT results render as a table, COUNT gives a summary, and write statements execute.</p>
139
139
  </div>
140
140
  <div class="page-actions">
141
141
  {{#unless readonly}}
142
142
  <button id="save-query" type="button" class="btn btn-outline btn-sm gap-1.5">
143
143
  {{{icon "save" class="h-4 w-4"}}}
144
144
  Save query
145
145
  </button>
146
146
  {{/unless}}
147
147
  <button id="run-query" type="button" class="btn btn-primary btn-sm gap-1.5">
148
148
  {{{icon "run" class="h-4 w-4"}}}
149
149
  Run query
150
150
  </button>
151
151
  </div>
152
152
  </div>
153
153
  </div>
154
154
  <div class="flex flex-wrap items-end gap-3">
155
155
  <div class="form-control w-full max-w-xs">
156
156
  <label class="field-label" for="saved-query-select">Saved queries</label>
157
157
  <select id="saved-query-select" class="field-select">
158
158
  <option value="">— select a saved query —</option>
159
159
  </select>
160
160
  </div>
161
161
  {{#unless readonly}}
162
162
  <button id="delete-query" type="button" class="btn btn-ghost btn-sm mb-0.5 text-error" disabled>Delete saved</button>
163
163
  <div class="form-control w-full max-w-xs">
164
164
  <label class="field-label" for="save-query-name">Save current SQL as</label>
165
165
  <div class="join w-full">
166
166
  <input id="save-query-name" type="text" class="field-input join-item !rounded-r-none" placeholder="query name" autocomplete="off" />
167
167
  <button id="save-query-inline" type="button" class="btn btn-outline join-item">Save</button>
168
168
  </div>
169
169
  </div>
170
170
  {{/unless}}
171
171
  </div>
172
172
  <div class="app-card overflow-hidden">
173
173
  <div class="flex flex-wrap items-center justify-between gap-2 border-b border-base-200 bg-base-200/40 px-4 py-2">
174
174
  <div class="flex items-center gap-2">
175
175
  <span class="flex items-center gap-1.5 text-xs font-semibold text-base-content/70">
176
176
  <span class="grid h-5 w-5 place-items-center rounded bg-primary/10 text-primary">
177
177
  {{{icon "query" class="h-3.5 w-3.5"}}}
178
178
  </span>
179
179
  query.sql
180
180
  </span>
181
181
  <span class="badge badge-sm badge-ghost font-mono text-[10px] uppercase font-bold">{{#if isPostgres}}Postgres{{else}}SQLite{{/if}}</span>
182
182
  </div>
183
183
  <div class="flex flex-wrap items-center gap-1.5">
184
184
  <div class="dropdown dropdown-end">
185
185
  <label tabindex="0" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary">
186
186
  {{{icon "terminal" class="h-3.5 w-3.5"}}}
187
187
  Snippets
188
188
  </label>
189
189
  <ul tabindex="0" class="dropdown-content z-30 menu p-1.5 shadow-2xl bg-base-100 rounded-xl w-56 border border-base-300 text-xs">
190
190
  <li class="menu-title text-[10px] uppercase tracking-wider text-base-content/40">Query Templates</li>
191
191
  <li><a class="js-snippet" data-snippet="SELECT * FROM table_name\nWHERE condition\nORDER BY id DESC\nLIMIT 50;">SELECT rows</a></li>
192
192
  <li><a class="js-snippet" data-snippet="SELECT COUNT(*) AS total\nFROM table_name;">COUNT summary</a></li>
193
193
  <li><a class="js-snippet" data-snippet="SELECT a.*, b.*\nFROM table_a a\nJOIN table_b b ON b.a_id = a.id\nLIMIT 50;">JOIN tables</a></li>
194
194
  <li><a class="js-snippet" data-snippet="INSERT INTO table_name (col1, col2)\nVALUES ('value1', 'value2');">INSERT row</a></li>
195
195
  <li><a class="js-snippet" data-snippet="UPDATE table_name\nSET col1 = 'value1'\nWHERE id = 1;">UPDATE row</a></li>
196
196
  <li><a class="js-snippet" data-snippet="DELETE FROM table_name\nWHERE id = 1;">DELETE row</a></li>
197
197
  <li><a class="js-snippet" data-snippet="CREATE TABLE new_table (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n);">CREATE TABLE</a></li>
198
198
  </ul>
199
199
  </div>
200
200
  <button id="format-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" title="Format SQL (Beautify)">
201
201
  {{{icon "format" class="h-3.5 w-3.5"}}}
202
202
  Format
203
203
  </button>
204
204
  <button id="copy-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" title="Copy SQL to clipboard">
205
205
  {{{icon "copy" class="h-3.5 w-3.5"}}}
206
206
  Copy
207
207
  </button>
208
208
  <button id="clear-query" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-error" title="Clear editor">
209
209
  {{{icon "trash" class="h-3.5 w-3.5"}}}
210
210
  Clear
211
211
  </button>
212
212
  <span class="hidden sm:inline-block text-[11px] text-base-content/35 border-l border-base-300 pl-2">Ctrl/⌘ + Enter to run</span>
213
213
  </div>
214
214
  </div>
215
215
  <div class="sql-editor-wrap">
216
216
  <div id="query-gutter" class="sql-gutter" aria-hidden="true">
217
217
  <div class="sql-gutter-line">1</div>
218
218
  </div>
219
219
  <div class="sql-editor-stage">
220
220
  <pre id="query-highlight" class="sql-code-highlight" aria-hidden="true"><code id="query-code"></code></pre>
221
221
  <textarea id="query-sql" class="sql-code-input" spellcheck="false" autocomplete="off" autocorrect="off" autocapitalize="off" placeholder="-- Write SQL here or choose a snippet/saved query&#10;SELECT * FROM table_name WHERE …"></textarea>
222
222
  </div>
223
223
  </div>
224
224
  <div class="flex items-center justify-between border-t border-base-200 bg-base-200/30 px-3.5 py-1.5 text-[11px] font-mono text-base-content/50">
225
225
  <div class="flex items-center gap-3">
226
226
  <span id="editor-cursor-pos">Ln 1, Col 1</span>
227
227
  <span id="editor-stats">0 chars</span>
228
228
  </div>
229
229
  <div class="flex items-center gap-2">
230
230
  <span class="text-[10px] text-base-content/40">Tab to indent · Ctrl+Z / Ctrl+Y to undo/redo · Ctrl+/ to comment</span>
231
231
  </div>
232
232
  </div>
233
233
  <div id="query-message" class="p-3"></div>
234
234
  </div>
235
235
  <div id="query-result" class="hidden">
236
236
  <div class="app-card overflow-hidden">
237
237
  <div class="flex items-center gap-2 border-b border-base-200 px-4 py-3">
238
238
  <span id="result-kind" class="grid h-6 w-6 place-items-center rounded-md bg-success/10 text-success">
239
239
  {{{icon "check" class="h-4 w-4"}}}
240
240
  </span>
241
241
  <span id="result-summary" class="text-sm font-medium text-base-content/60"></span>
242
242
  <div class="ml-auto flex items-center gap-1.5">
243
243
  <button id="export-csv" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" disabled>
244
244
  {{{icon "export" class="h-3.5 w-3.5"}}}
245
245
  CSV
246
246
  </button>
247
247
  <button id="export-json" type="button" class="btn btn-ghost btn-xs gap-1 text-base-content/70 hover:text-primary" disabled>
248
248
  {{{icon "export" class="h-3.5 w-3.5"}}}
249
249
  JSON
250
250
  </button>
251
251
  </div>
252
252
  </div>
253
253
  <div class="overflow-x-auto">
254
254
  <table class="table table-sm table-pin-rows">
255
255
  <thead id="query-result-head" class="bg-base-200/70 text-xs uppercase tracking-wide text-base-content/50"></thead>
256
256
  <tbody id="query-result-body"></tbody>
257
257
  </table>
258
258
  </div>
259
259
  </div>
260
260
  </div>