sqlite-hub 1.1.1 → 1.1.2
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.
- package/README.md +17 -196
- package/bin/sqlite-hub.js +7 -2
- package/frontend/js/api.js +60 -0
- package/frontend/js/app.js +110 -0
- package/frontend/js/components/dropdownButton.js +92 -0
- package/frontend/js/components/modal.js +991 -876
- package/frontend/js/components/queryEditor.js +24 -15
- package/frontend/js/components/queryHistoryDetail.js +20 -1
- package/frontend/js/components/queryHistoryHeader.js +3 -2
- package/frontend/js/components/rowEditorPanel.js +1 -0
- package/frontend/js/components/sidebar.js +1 -0
- package/frontend/js/router.js +2 -0
- package/frontend/js/store.js +383 -37
- package/frontend/js/utils/riskySql.js +165 -0
- package/frontend/js/views/backups.js +176 -0
- package/frontend/js/views/charts.js +1 -1
- package/frontend/js/views/documents.js +184 -154
- package/frontend/js/views/structure.js +26 -24
- package/frontend/styles/components.css +128 -0
- package/frontend/styles/tailwind.generated.css +1 -1
- package/frontend/styles/views.css +33 -21
- package/package.json +2 -1
- package/server/routes/backups.js +120 -0
- package/server/routes/connections.js +26 -3
- package/server/routes/externalApi.js +6 -2
- package/server/server.js +3 -1
- package/server/services/databaseCommandService.js +4 -3
- package/server/services/sqlite/backupService.js +497 -66
- package/server/services/sqlite/connectionManager.js +2 -2
- package/server/services/sqlite/importService.js +25 -0
- package/server/services/sqlite/sqlExecutor.js +2 -0
- package/server/services/storage/appStateStore.js +379 -88
- package/tests/api-token-auth.test.js +45 -2
- package/tests/backup-manager.test.js +140 -0
- package/tests/backups-view.test.js +64 -0
- package/tests/charts-height-preset-storage.test.js +60 -0
- package/tests/charts-route-state.test.js +144 -0
- package/tests/cli-service-delegation.test.js +97 -0
- package/tests/connection-removal.test.js +52 -0
- package/tests/database-command-service.test.js +37 -2
- package/tests/documents-view.test.js +132 -0
- package/tests/dropdown-button.test.js +75 -0
- package/tests/query-editor.test.js +28 -0
- package/tests/query-history-detail.test.js +37 -0
- package/tests/query-history-header.test.js +30 -0
- package/tests/risky-sql.test.js +30 -0
- package/tests/row-editor-null-values.test.js +24 -0
- package/tests/structure-view.test.js +56 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { renderDropdownButton } from '../components/dropdownButton.js';
|
|
1
2
|
import { escapeHtml, formatCompactDateTime, formatNumber } from '../utils/format.js';
|
|
2
3
|
import { renderMarkdownPreview } from '../utils/markdownDocuments.js';
|
|
3
4
|
|
|
@@ -100,164 +101,191 @@ function renderDocumentsSidebar(documents) {
|
|
|
100
101
|
`;
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
function
|
|
104
|
+
function renderDocumentImportFileInput() {
|
|
105
|
+
return `
|
|
106
|
+
<input
|
|
107
|
+
accept=".md,.markdown,text/markdown,text/plain"
|
|
108
|
+
data-bind="document-import-file"
|
|
109
|
+
hidden
|
|
110
|
+
type="file"
|
|
111
|
+
/>
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function renderNewDocumentDropdown(documents, className = '') {
|
|
116
|
+
return `
|
|
117
|
+
<div class="${escapeHtml(className)}">
|
|
118
|
+
${renderDropdownButton({
|
|
119
|
+
disabled: documents.saving,
|
|
120
|
+
icon: 'add',
|
|
121
|
+
label: 'New Document',
|
|
122
|
+
title: 'New document',
|
|
123
|
+
items: [
|
|
124
|
+
{
|
|
125
|
+
action: 'create-document',
|
|
126
|
+
icon: 'draft',
|
|
127
|
+
label: 'Blank Page',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
action: 'import-document-markdown',
|
|
131
|
+
icon: 'upload_file',
|
|
132
|
+
label: 'Import .md',
|
|
133
|
+
},
|
|
134
|
+
],
|
|
135
|
+
})}
|
|
136
|
+
</div>
|
|
137
|
+
`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function renderDocumentsPanelToggle(documents) {
|
|
141
|
+
const visible = documents.documentsVisible !== false;
|
|
142
|
+
|
|
143
|
+
return `
|
|
144
|
+
<button
|
|
145
|
+
class="standard-button panel-toggle-button ${visible ? '' : 'is-active'}"
|
|
146
|
+
aria-pressed="${visible ? 'false' : 'true'}"
|
|
147
|
+
data-action="toggle-documents-panel"
|
|
148
|
+
type="button"
|
|
149
|
+
>
|
|
150
|
+
<span class="material-symbols-outlined">${visible ? 'visibility_off' : 'visibility'}</span>
|
|
151
|
+
${visible ? 'Hide Documents' : 'Show Documents'}
|
|
152
|
+
</button>
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function renderDocumentPaneToggle(documents, pane) {
|
|
157
|
+
const isEditor = pane === 'editor';
|
|
158
|
+
const visible = isEditor ? documents.editorVisible : documents.previewVisible;
|
|
159
|
+
const label = `${visible ? 'Hide' : 'Show'} ${isEditor ? 'Editor' : 'Preview'}`;
|
|
160
|
+
const icon = visible ? 'visibility_off' : isEditor ? 'edit_note' : 'visibility';
|
|
161
|
+
|
|
162
|
+
return `
|
|
163
|
+
<button
|
|
164
|
+
class="standard-button panel-toggle-button documents-pane__toggle ${visible ? '' : 'is-active'}"
|
|
165
|
+
aria-pressed="${visible ? 'false' : 'true'}"
|
|
166
|
+
data-action="toggle-document-pane"
|
|
167
|
+
data-pane="${escapeHtml(pane)}"
|
|
168
|
+
type="button"
|
|
169
|
+
>
|
|
170
|
+
<span class="material-symbols-outlined">${icon}</span>
|
|
171
|
+
${label}
|
|
172
|
+
</button>
|
|
173
|
+
`;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function renderDocumentsTitlebar(documents, options = {}) {
|
|
177
|
+
const { showDocumentActions = false, showFilename = true } = options;
|
|
104
178
|
const disabled = documents.saving || documents.detailLoading || !documents.selectedId;
|
|
105
179
|
|
|
106
180
|
return `
|
|
107
181
|
<div class="documents-titlebar">
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
Insert Table
|
|
171
|
-
</button>
|
|
172
|
-
<button
|
|
173
|
-
class="standard-button"
|
|
174
|
-
data-action="open-document-insert-note-modal"
|
|
175
|
-
type="button"
|
|
176
|
-
${disabled ? 'disabled aria-disabled="true"' : ''}
|
|
177
|
-
>
|
|
178
|
-
<span class="material-symbols-outlined">note_add</span>
|
|
179
|
-
Insert Note
|
|
180
|
-
</button>
|
|
181
|
-
<button
|
|
182
|
-
class="standard-button"
|
|
183
|
-
data-action="export-document-markdown"
|
|
184
|
-
type="button"
|
|
185
|
-
${disabled ? 'disabled aria-disabled="true"' : ''}
|
|
186
|
-
>
|
|
187
|
-
<span class="material-symbols-outlined">download</span>
|
|
188
|
-
Export .md
|
|
189
|
-
</button>
|
|
190
|
-
<button
|
|
191
|
-
class="standard-button"
|
|
192
|
-
data-action="import-document-markdown"
|
|
193
|
-
type="button"
|
|
194
|
-
${documents.saving ? 'disabled aria-disabled="true"' : ''}
|
|
195
|
-
>
|
|
196
|
-
<span class="material-symbols-outlined">upload_file</span>
|
|
197
|
-
Import .md
|
|
198
|
-
</button>
|
|
199
|
-
</div>
|
|
200
|
-
<div class="documents-toolbar__actions">
|
|
201
|
-
<button
|
|
202
|
-
class="standard-button"
|
|
203
|
-
data-action="delete-document"
|
|
204
|
-
type="button"
|
|
205
|
-
${disabled || documents.deleting ? 'disabled aria-disabled="true"' : ''}
|
|
206
|
-
>
|
|
207
|
-
<span class="material-symbols-outlined">delete</span>
|
|
208
|
-
Delete
|
|
209
|
-
</button>
|
|
210
|
-
<button
|
|
211
|
-
class="signature-button"
|
|
212
|
-
data-action="save-document"
|
|
213
|
-
type="button"
|
|
214
|
-
${disabled || !documents.dirty ? 'disabled aria-disabled="true"' : ''}
|
|
215
|
-
>
|
|
216
|
-
<span class="material-symbols-outlined">save</span>
|
|
217
|
-
${documents.saving ? 'Saving...' : 'Save'}
|
|
218
|
-
</button>
|
|
219
|
-
</div>
|
|
182
|
+
${renderDocumentsPanelToggle(documents)}
|
|
183
|
+
${
|
|
184
|
+
showFilename
|
|
185
|
+
? `
|
|
186
|
+
<label class="documents-filename-field">
|
|
187
|
+
<input
|
|
188
|
+
class="control-input"
|
|
189
|
+
data-bind="document-field"
|
|
190
|
+
data-field="filename"
|
|
191
|
+
name="filename"
|
|
192
|
+
spellcheck="false"
|
|
193
|
+
type="text"
|
|
194
|
+
value="${escapeHtml(documents.draftFilename)}"
|
|
195
|
+
${!documents.selectedId ? 'disabled' : ''}
|
|
196
|
+
/>
|
|
197
|
+
</label>
|
|
198
|
+
`
|
|
199
|
+
: ''
|
|
200
|
+
}
|
|
201
|
+
${renderNewDocumentDropdown(documents, 'documents-create-button')}
|
|
202
|
+
${
|
|
203
|
+
showDocumentActions
|
|
204
|
+
? `
|
|
205
|
+
${renderDropdownButton({
|
|
206
|
+
disabled,
|
|
207
|
+
icon: 'add_box',
|
|
208
|
+
label: 'Insert',
|
|
209
|
+
title: 'Insert content',
|
|
210
|
+
items: [
|
|
211
|
+
{
|
|
212
|
+
action: 'open-document-insert-table-modal',
|
|
213
|
+
icon: 'table_chart',
|
|
214
|
+
label: 'Insert Table',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
action: 'open-document-insert-note-modal',
|
|
218
|
+
icon: 'note_add',
|
|
219
|
+
label: 'Insert Note',
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
})}
|
|
223
|
+
<button
|
|
224
|
+
class="standard-button"
|
|
225
|
+
data-action="export-document-markdown"
|
|
226
|
+
type="button"
|
|
227
|
+
${disabled ? 'disabled aria-disabled="true"' : ''}
|
|
228
|
+
>
|
|
229
|
+
<span class="material-symbols-outlined">download</span>
|
|
230
|
+
Export .md
|
|
231
|
+
</button>
|
|
232
|
+
<button
|
|
233
|
+
class="delete-button"
|
|
234
|
+
data-action="delete-document"
|
|
235
|
+
type="button"
|
|
236
|
+
${disabled || documents.deleting ? 'disabled aria-disabled="true"' : ''}
|
|
237
|
+
>
|
|
238
|
+
<span class="material-symbols-outlined">delete</span>
|
|
239
|
+
Delete
|
|
240
|
+
</button>
|
|
241
|
+
`
|
|
242
|
+
: ''
|
|
243
|
+
}
|
|
220
244
|
</div>
|
|
221
245
|
`;
|
|
222
246
|
}
|
|
223
247
|
|
|
224
248
|
function renderDocumentEditor(documents) {
|
|
225
|
-
if (!documents.editorVisible) {
|
|
226
|
-
return '';
|
|
227
|
-
}
|
|
228
|
-
|
|
229
249
|
return `
|
|
230
|
-
<section class="documents-pane documents-pane--editor">
|
|
250
|
+
<section class="documents-pane documents-pane--editor ${documents.editorVisible ? '' : 'documents-pane--collapsed'}">
|
|
231
251
|
<div class="documents-pane__header">
|
|
232
|
-
|
|
233
|
-
<span>${formatNumber(documents.draftContent.length)} chars</span>
|
|
252
|
+
${renderDocumentPaneToggle(documents, 'editor')}
|
|
253
|
+
<span class="documents-pane__meta">${formatNumber(documents.draftContent.length)} chars</span>
|
|
234
254
|
</div>
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
255
|
+
${
|
|
256
|
+
documents.editorVisible
|
|
257
|
+
? `
|
|
258
|
+
<textarea
|
|
259
|
+
class="documents-editor-input custom-scrollbar"
|
|
260
|
+
data-bind="document-field"
|
|
261
|
+
data-field="content"
|
|
262
|
+
name="content"
|
|
263
|
+
spellcheck="true"
|
|
264
|
+
${!documents.selectedId ? 'disabled' : ''}
|
|
265
|
+
>${escapeHtml(documents.draftContent)}</textarea>
|
|
266
|
+
`
|
|
267
|
+
: ''
|
|
268
|
+
}
|
|
243
269
|
</section>
|
|
244
270
|
`;
|
|
245
271
|
}
|
|
246
272
|
|
|
247
273
|
function renderDocumentPreview(documents) {
|
|
248
|
-
if (!documents.previewVisible) {
|
|
249
|
-
return '';
|
|
250
|
-
}
|
|
251
|
-
|
|
252
274
|
return `
|
|
253
|
-
<section class="documents-pane documents-pane--preview">
|
|
275
|
+
<section class="documents-pane documents-pane--preview ${documents.previewVisible ? '' : 'documents-pane--collapsed'}">
|
|
254
276
|
<div class="documents-pane__header">
|
|
255
|
-
|
|
256
|
-
<span>${escapeHtml(documents.dirty ? 'unsaved' : 'saved')}</span>
|
|
257
|
-
</div>
|
|
258
|
-
<div class="document-markdown-preview custom-scrollbar" data-document-preview>
|
|
259
|
-
${renderMarkdownPreview(documents.draftContent)}
|
|
277
|
+
${renderDocumentPaneToggle(documents, 'preview')}
|
|
278
|
+
<span class="documents-pane__meta">${escapeHtml(documents.dirty ? 'unsaved' : 'saved')}</span>
|
|
260
279
|
</div>
|
|
280
|
+
${
|
|
281
|
+
documents.previewVisible
|
|
282
|
+
? `
|
|
283
|
+
<div class="document-markdown-preview custom-scrollbar" data-document-preview>
|
|
284
|
+
${renderMarkdownPreview(documents.draftContent)}
|
|
285
|
+
</div>
|
|
286
|
+
`
|
|
287
|
+
: ''
|
|
288
|
+
}
|
|
261
289
|
</section>
|
|
262
290
|
`;
|
|
263
291
|
}
|
|
@@ -269,15 +297,7 @@ function renderEmptyDocumentsState(documents) {
|
|
|
269
297
|
<p class="font-headline text-2xl font-black uppercase tracking-tight text-primary-container">
|
|
270
298
|
No Documents
|
|
271
299
|
</p>
|
|
272
|
-
|
|
273
|
-
class="signature-button mt-4"
|
|
274
|
-
data-action="create-document"
|
|
275
|
-
type="button"
|
|
276
|
-
${documents.saving ? 'disabled aria-disabled="true"' : ''}
|
|
277
|
-
>
|
|
278
|
-
<span class="material-symbols-outlined">add</span>
|
|
279
|
-
New Document
|
|
280
|
-
</button>
|
|
300
|
+
${renderNewDocumentDropdown(documents, 'mt-4')}
|
|
281
301
|
</div>
|
|
282
302
|
`;
|
|
283
303
|
}
|
|
@@ -286,6 +306,7 @@ function renderDocumentDetail(documents) {
|
|
|
286
306
|
if (documents.loading && !documents.items.length) {
|
|
287
307
|
return `
|
|
288
308
|
<main class="documents-view__detail">
|
|
309
|
+
${renderDocumentsTitlebar(documents, { showFilename: false })}
|
|
289
310
|
<div class="documents-empty-state">
|
|
290
311
|
<span class="material-symbols-outlined">sync</span>
|
|
291
312
|
<p class="font-headline text-2xl font-black uppercase tracking-tight text-primary-container">
|
|
@@ -299,18 +320,26 @@ function renderDocumentDetail(documents) {
|
|
|
299
320
|
if (!documents.selectedId) {
|
|
300
321
|
return `
|
|
301
322
|
<main class="documents-view__detail">
|
|
323
|
+
${renderDocumentsTitlebar(documents, { showFilename: false })}
|
|
302
324
|
${renderEmptyDocumentsState(documents)}
|
|
303
325
|
</main>
|
|
304
326
|
`;
|
|
305
327
|
}
|
|
306
328
|
|
|
307
|
-
const
|
|
329
|
+
const workspaceClasses = [
|
|
330
|
+
'documents-workspace',
|
|
331
|
+
documents.editorVisible && documents.previewVisible ? 'documents-workspace--split' : '',
|
|
332
|
+
!documents.editorVisible ? 'documents-workspace--editor-collapsed' : '',
|
|
333
|
+
!documents.previewVisible ? 'documents-workspace--preview-collapsed' : '',
|
|
334
|
+
]
|
|
335
|
+
.filter(Boolean)
|
|
336
|
+
.join(' ');
|
|
308
337
|
|
|
309
338
|
return `
|
|
310
339
|
<main class="documents-view__detail">
|
|
311
|
-
${
|
|
340
|
+
${renderDocumentsTitlebar(documents, { showDocumentActions: true })}
|
|
312
341
|
${documents.saveError ? `<div class="documents-error">${escapeHtml(documents.saveError.message)}</div>` : ''}
|
|
313
|
-
<div class="
|
|
342
|
+
<div class="${workspaceClasses}">
|
|
314
343
|
${renderDocumentEditor(documents)}
|
|
315
344
|
${renderDocumentPreview(documents)}
|
|
316
345
|
</div>
|
|
@@ -327,13 +356,14 @@ export function renderDocumentsView(state) {
|
|
|
327
356
|
}
|
|
328
357
|
|
|
329
358
|
const documents = state.documents;
|
|
359
|
+
const documentsVisible = documents.documentsVisible !== false;
|
|
330
360
|
|
|
331
361
|
return {
|
|
332
|
-
main: `<div class="documents-view">
|
|
333
|
-
${
|
|
362
|
+
main: `<div class="documents-view ${documentsVisible ? 'documents-view--with-subnavi' : ''}">
|
|
363
|
+
${renderDocumentImportFileInput()}
|
|
364
|
+
${documentsVisible ? renderDocumentsSidebar(documents) : ''}
|
|
334
365
|
${renderDocumentDetail(documents)}
|
|
335
|
-
</div
|
|
336
|
-
</div>`,
|
|
366
|
+
</div>`,
|
|
337
367
|
panel: '',
|
|
338
368
|
};
|
|
339
369
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { clearInspector, renderDdlSection, renderInspector } from '../components/structureGraph.js';
|
|
2
|
+
import { renderDropdownButton } from '../components/dropdownButton.js';
|
|
2
3
|
import { escapeHtml, formatNumber } from '../utils/format.js';
|
|
3
4
|
|
|
4
5
|
function renderEntryGroup(title, entries, activeName, options = {}) {
|
|
@@ -230,30 +231,31 @@ function renderGraphSurface(structure, selectedName, detail, detailLoading, tabl
|
|
|
230
231
|
</button>
|
|
231
232
|
</div>
|
|
232
233
|
<div class="structure-graph__toolbar-actions">
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
234
|
+
${renderDropdownButton({
|
|
235
|
+
icon: 'format_shapes',
|
|
236
|
+
label: 'Format',
|
|
237
|
+
title: 'Format graph',
|
|
238
|
+
items: [
|
|
239
|
+
{
|
|
240
|
+
action: 'fit',
|
|
241
|
+
actionAttribute: 'data-structure-graph-action',
|
|
242
|
+
icon: 'fit_screen',
|
|
243
|
+
label: 'Fit Graph',
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
action: 'relayout',
|
|
247
|
+
actionAttribute: 'data-structure-graph-action',
|
|
248
|
+
icon: 'device_hub',
|
|
249
|
+
label: 'Recalculate Layout',
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
action: 'clear',
|
|
253
|
+
actionAttribute: 'data-structure-graph-action',
|
|
254
|
+
icon: 'close',
|
|
255
|
+
label: 'Clear Selection',
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
})}
|
|
257
259
|
<button
|
|
258
260
|
class="${toolbarButtonClass}"
|
|
259
261
|
data-structure-graph-action="open-data"
|
|
@@ -477,6 +477,7 @@
|
|
|
477
477
|
.signature-button,
|
|
478
478
|
.delete-button,
|
|
479
479
|
.toolbar-button,
|
|
480
|
+
.dropdown-button__toggle,
|
|
480
481
|
.query-history-icon-button,
|
|
481
482
|
.top-nav-icon {
|
|
482
483
|
align-items: center;
|
|
@@ -532,10 +533,29 @@
|
|
|
532
533
|
text-transform: uppercase;
|
|
533
534
|
}
|
|
534
535
|
|
|
536
|
+
.backup-safety-actions {
|
|
537
|
+
align-items: center;
|
|
538
|
+
display: flex;
|
|
539
|
+
flex-wrap: nowrap;
|
|
540
|
+
gap: var(--spacing-3);
|
|
541
|
+
overflow-x: auto;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.backup-safety-actions > button {
|
|
545
|
+
flex: 0 0 auto;
|
|
546
|
+
white-space: nowrap;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.backup-safety-actions > .standard-button {
|
|
550
|
+
margin-right: auto;
|
|
551
|
+
}
|
|
552
|
+
|
|
535
553
|
.standard-button:focus-visible,
|
|
536
554
|
.signature-button:focus-visible,
|
|
537
555
|
.delete-button:focus-visible,
|
|
538
556
|
.toolbar-button:focus-visible,
|
|
557
|
+
.dropdown-button__toggle:focus-visible,
|
|
558
|
+
.dropdown-button__item:focus-visible,
|
|
539
559
|
.query-result-column-menu__toggle:focus-visible,
|
|
540
560
|
.query-result-column-menu__item:focus-visible,
|
|
541
561
|
.query-history-icon-button:focus-visible,
|
|
@@ -566,6 +586,94 @@
|
|
|
566
586
|
color var(--transition-fast);
|
|
567
587
|
}
|
|
568
588
|
|
|
589
|
+
.dropdown-button {
|
|
590
|
+
display: inline-flex;
|
|
591
|
+
position: relative;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.dropdown-button__toggle {
|
|
595
|
+
cursor: pointer;
|
|
596
|
+
gap: var(--spacing-2);
|
|
597
|
+
list-style: none;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
.dropdown-button__toggle::-webkit-details-marker {
|
|
601
|
+
display: none;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
.dropdown-button[open] .dropdown-button__toggle {
|
|
605
|
+
background: var(--primary-alpha-12);
|
|
606
|
+
border-color: rgb(var(--rgb-primary) / 0.38);
|
|
607
|
+
color: var(--color-primary-container);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
.dropdown-button__chevron {
|
|
611
|
+
font-size: 18px;
|
|
612
|
+
line-height: 1;
|
|
613
|
+
transition: transform var(--transition-fast);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
.dropdown-button[open] .dropdown-button__chevron {
|
|
617
|
+
transform: rotate(180deg);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
.dropdown-button__panel {
|
|
621
|
+
background: var(--color-surface-container);
|
|
622
|
+
border: 1px solid rgb(var(--rgb-outline) / 0.22);
|
|
623
|
+
box-shadow: 0 18px 40px rgb(0 0 0 / 0.35);
|
|
624
|
+
min-width: 13rem;
|
|
625
|
+
padding: var(--spacing-1);
|
|
626
|
+
position: absolute;
|
|
627
|
+
top: calc(100% + var(--spacing-2));
|
|
628
|
+
z-index: 35;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.dropdown-button--align-right .dropdown-button__panel {
|
|
632
|
+
right: 0;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
.dropdown-button--align-left .dropdown-button__panel {
|
|
636
|
+
left: 0;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.dropdown-button__item {
|
|
640
|
+
align-items: center;
|
|
641
|
+
color: var(--color-on-surface);
|
|
642
|
+
cursor: pointer;
|
|
643
|
+
display: flex;
|
|
644
|
+
font-family: var(--font-family-body);
|
|
645
|
+
font-size: 0.75rem;
|
|
646
|
+
gap: var(--spacing-2);
|
|
647
|
+
justify-content: flex-start;
|
|
648
|
+
line-height: 1.3;
|
|
649
|
+
padding: 0.6rem 0.75rem;
|
|
650
|
+
text-align: left;
|
|
651
|
+
transition:
|
|
652
|
+
background-color var(--transition-fast),
|
|
653
|
+
color var(--transition-fast);
|
|
654
|
+
width: 100%;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
.dropdown-button__item:hover {
|
|
658
|
+
background: var(--color-surface-highest);
|
|
659
|
+
color: var(--color-primary-container);
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
.dropdown-button__item:disabled,
|
|
663
|
+
.dropdown-button__item[aria-disabled='true'] {
|
|
664
|
+
color: rgb(var(--rgb-on-surface-variant) / 0.32);
|
|
665
|
+
cursor: not-allowed;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.dropdown-button__item--danger {
|
|
669
|
+
color: var(--color-error);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
.dropdown-button__item .material-symbols-outlined {
|
|
673
|
+
font-size: 18px;
|
|
674
|
+
line-height: 1;
|
|
675
|
+
}
|
|
676
|
+
|
|
569
677
|
.query-result-header-cell {
|
|
570
678
|
min-width: 10rem;
|
|
571
679
|
position: relative;
|
|
@@ -890,6 +998,26 @@
|
|
|
890
998
|
text-transform: uppercase;
|
|
891
999
|
}
|
|
892
1000
|
|
|
1001
|
+
.query-history-search {
|
|
1002
|
+
display: block;
|
|
1003
|
+
margin-top: var(--spacing-4);
|
|
1004
|
+
position: relative;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
.query-history-search__icon {
|
|
1008
|
+
color: rgb(var(--rgb-on-surface-variant) / 0.55);
|
|
1009
|
+
font-size: 1rem;
|
|
1010
|
+
left: var(--spacing-3);
|
|
1011
|
+
pointer-events: none;
|
|
1012
|
+
position: absolute;
|
|
1013
|
+
top: 50%;
|
|
1014
|
+
transform: translateY(-50%);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
.query-history-search__input {
|
|
1018
|
+
padding-left: calc(var(--spacing-3) + 1rem + var(--spacing-2));
|
|
1019
|
+
}
|
|
1020
|
+
|
|
893
1021
|
.query-history-list-scroll {
|
|
894
1022
|
flex: 1;
|
|
895
1023
|
min-height: 0;
|