sqlite-hub 1.2.0 → 1.4.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.
- package/README.md +106 -73
- package/bin/sqlite-hub.js +176 -2
- package/docs/API.md +122 -0
- package/docs/CLI.md +227 -0
- package/docs/DESIGN_GUIDELINES.md +45 -0
- package/docs/changelog.md +141 -0
- package/docs/shortkeys.md +27 -0
- package/docs/todo.md +16 -0
- package/examples/api/generate-types.js +52 -0
- package/frontend/assets/mockups/backups_1_1920.webp +0 -0
- package/frontend/assets/mockups/backups_2_create_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_3_edit_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_4_restore_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_5_delete_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_1_1920.webp +0 -0
- package/frontend/assets/mockups/charts_2_query_detail_1920.webp +0 -0
- package/frontend/assets/mockups/charts_3_create_query_chart_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_4_edit_query_chart_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_5_delete_query_chart_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_6_copy_column_modal_1920.webp +0 -0
- package/frontend/assets/mockups/connections_1_1920.webp +0 -0
- package/frontend/assets/mockups/connections_2_create_connection_modal_1920.webp +0 -0
- package/frontend/assets/mockups/connections_3_open_connection_modal_1920.webp +0 -0
- package/frontend/assets/mockups/data_1_1920.webp +0 -0
- package/frontend/assets/mockups/data_2_roweditor_1920.webp +0 -0
- package/frontend/assets/mockups/data_3_data_export_modal_1920.webp +0 -0
- package/frontend/assets/mockups/documents_1_1920.webp +0 -0
- package/frontend/assets/mockups/documents_2_document_insert_table_modal_1920.webp +0 -0
- package/frontend/assets/mockups/documents_3_document_insert_note_modal_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_queue_1_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_setup_1_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_setup_2_create_media_tagging_tag_table_modal_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_setup_3_create_media_tagging_mapping_table_modal_1920.webp +0 -0
- package/frontend/assets/mockups/overview_1_1920.webp +0 -0
- package/frontend/assets/mockups/settings_1_1920.webp +0 -0
- package/frontend/assets/mockups/sql_editor_1_1920.webp +0 -0
- package/frontend/assets/mockups/sql_editor_2_query_detail_1920.webp +0 -0
- package/frontend/assets/mockups/sql_editor_3_query_export_modal_1920.webp +0 -0
- package/frontend/assets/mockups/structure_1_1920.webp +0 -0
- package/frontend/assets/mockups/structure_2_generate_types_modal_1920.webp +0 -0
- package/frontend/assets/mockups/structure_3_generate_types_modal_1920.webp +0 -0
- package/frontend/assets/mockups/table_designer_1_1920.webp +0 -0
- package/frontend/assets/mockups/table_designer_2_table_designer_constraints_modal_1920.webp +0 -0
- package/frontend/js/api.js +18 -0
- package/frontend/js/app.js +118 -8
- package/frontend/js/components/connectionCard.js +1 -1
- package/frontend/js/components/emptyState.js +4 -4
- package/frontend/js/components/generateTypesDropdown.js +33 -0
- package/frontend/js/components/metricCard.js +1 -1
- package/frontend/js/components/modal.js +211 -18
- package/frontend/js/components/pageHeader.js +1 -1
- package/frontend/js/components/queryHistoryDetail.js +3 -3
- package/frontend/js/components/queryHistoryHeader.js +1 -1
- package/frontend/js/components/queryHistoryPanel.js +1 -1
- package/frontend/js/components/rowEditorPanel.js +13 -3
- package/frontend/js/router.js +28 -6
- package/frontend/js/store.js +422 -8
- package/frontend/js/views/backups.js +529 -37
- package/frontend/js/views/charts.js +9 -9
- package/frontend/js/views/connections.js +2 -2
- package/frontend/js/views/data.js +1 -1
- package/frontend/js/views/documents.js +3 -3
- package/frontend/js/views/editor.js +6 -6
- package/frontend/js/views/mediaTagging.js +7 -5
- package/frontend/js/views/overview.js +3 -3
- package/frontend/js/views/settings.js +3 -3
- package/frontend/js/views/structure.js +6 -1
- package/frontend/styles/base.css +1 -40
- package/frontend/styles/components.css +109 -232
- package/frontend/styles/structure-graph.css +32 -68
- package/frontend/styles/tailwind.css +8 -4
- package/frontend/styles/tailwind.generated.css +1 -1
- package/frontend/styles/tokens.css +28 -21
- package/frontend/styles/views.css +94 -261
- package/package.json +18 -2
- package/server/routes/backups.js +18 -2
- package/server/routes/externalApi.js +36 -0
- package/server/routes/structure.js +22 -0
- package/server/services/databaseCommandService.js +14 -0
- package/server/services/sqlite/backupDiff.js +914 -0
- package/server/services/sqlite/backupService.js +77 -1
- package/server/services/sqlite/structureService.js +7 -0
- package/server/services/typeGenerationService.js +663 -0
- package/tailwind.config.cjs +0 -1
- package/.github/funding.yml +0 -2
- package/.github/workflows/ci.yml +0 -36
- package/database.sqlite +0 -0
- package/frontend/assets/mockups/charts_1_bars_1200.webp +0 -0
- package/frontend/assets/mockups/charts_2_pie_1200.webp +0 -0
- package/frontend/assets/mockups/charts_3_scatter_plot_1200.webp +0 -0
- package/frontend/assets/mockups/connections_1200.webp +0 -0
- package/frontend/assets/mockups/data_1_1200.webp +0 -0
- package/frontend/assets/mockups/data_2_row_editor_1200.webp +0 -0
- package/frontend/assets/mockups/documents_1200.webp +0 -0
- package/frontend/assets/mockups/media_tagging_1_setup_1200.webp +0 -0
- package/frontend/assets/mockups/media_tagging_2_tagging_queue_1200.webp +0 -0
- package/frontend/assets/mockups/media_tagging_3_media_viewer_1200.webp +0 -0
- package/frontend/assets/mockups/overview_1200.webp +0 -0
- package/frontend/assets/mockups/settings_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_1_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_2_query_details_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_3_export_column_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_4_export_column_as_markdown_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_5_export_query_result_1200.webp +0 -0
- package/frontend/assets/mockups/structure_1_1200.webp +0 -0
- package/frontend/assets/mockups/structure_2_inspector_1200.webp +0 -0
- package/frontend/assets/mockups/table_designer_1_1200.webp +0 -0
- package/frontend/assets/mockups/table_designer_2_checks_1200.webp +0 -0
- package/tests/api-token-auth.test.js +0 -279
- package/tests/backup-manager.test.js +0 -140
- package/tests/backups-view.test.js +0 -70
- package/tests/charts-height-preset-storage.test.js +0 -60
- package/tests/charts-route-state.test.js +0 -144
- package/tests/check-constraint-options.test.js +0 -90
- package/tests/cli-args.test.js +0 -113
- package/tests/cli-service-delegation.test.js +0 -140
- package/tests/connection-removal.test.js +0 -52
- package/tests/connections-file-dialog-route.test.js +0 -89
- package/tests/copy-column-modal.test.js +0 -131
- package/tests/database-command-service.test.js +0 -174
- package/tests/database-documents.test.js +0 -85
- package/tests/documents-view.test.js +0 -132
- package/tests/dropdown-button.test.js +0 -101
- package/tests/email-preview.test.js +0 -89
- package/tests/export-blob.test.js +0 -99
- package/tests/export-filenames.test.js +0 -38
- package/tests/file-path-preview.test.js +0 -165
- package/tests/form-controls.test.js +0 -34
- package/tests/json-preview.test.js +0 -49
- package/tests/local-request-security.test.js +0 -85
- package/tests/markdown-documents.test.js +0 -103
- package/tests/native-file-dialog.test.js +0 -105
- package/tests/query-editor.test.js +0 -28
- package/tests/query-history-detail.test.js +0 -37
- package/tests/query-history-header.test.js +0 -30
- package/tests/query-results-truncation.test.js +0 -20
- package/tests/risky-sql.test.js +0 -30
- package/tests/row-editor-json.test.js +0 -82
- package/tests/row-editor-null-values.test.js +0 -184
- package/tests/row-editor-timestamp-preview.test.js +0 -192
- package/tests/security-paths.test.js +0 -84
- package/tests/settings-api-tokens-route.test.js +0 -97
- package/tests/settings-metadata.test.js +0 -114
- package/tests/settings-view.test.js +0 -108
- package/tests/sql-formatter.test.js +0 -173
- package/tests/sql-highlight.test.js +0 -38
- package/tests/sql-identifier-safety.test.js +0 -171
- package/tests/sql-result-limit.test.js +0 -66
- package/tests/structure-view.test.js +0 -60
- package/tests/table-designer-v2-unique-constraints.test.js +0 -78
- package/tests/table-scroll-state.test.js +0 -70
- package/tests/text-cell-stats.test.js +0 -38
|
Binary file
|
package/frontend/assets/mockups/media_tagging_setup_2_create_media_tagging_tag_table_modal_1920.webp
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/frontend/js/api.js
CHANGED
|
@@ -153,6 +153,17 @@ export function getBackup(backupId) {
|
|
|
153
153
|
return request(`/api/backups/${encodeURIComponent(backupId)}`);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
export function getBackupDiff(backupId, options = {}) {
|
|
157
|
+
const params = new URLSearchParams();
|
|
158
|
+
|
|
159
|
+
if (options.sampleLimit !== undefined) {
|
|
160
|
+
params.set("sampleLimit", String(options.sampleLimit));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const query = params.toString();
|
|
164
|
+
return request(`/api/backups/${encodeURIComponent(backupId)}/diff${query ? `?${query}` : ""}`);
|
|
165
|
+
}
|
|
166
|
+
|
|
156
167
|
export function createBackup(payload = {}) {
|
|
157
168
|
return request("/api/backups", {
|
|
158
169
|
method: "POST",
|
|
@@ -340,6 +351,13 @@ export function getStructureDetail(tableName) {
|
|
|
340
351
|
return request(`/api/structure/${encodeURIComponent(tableName)}`);
|
|
341
352
|
}
|
|
342
353
|
|
|
354
|
+
export function generateStructureTypes(tableName, payload = {}) {
|
|
355
|
+
return request(`/api/structure/${encodeURIComponent(tableName)}/types`, {
|
|
356
|
+
method: "POST",
|
|
357
|
+
body: payload,
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
|
|
343
361
|
export function getTableDesignerOverview() {
|
|
344
362
|
return request("/api/table-designer");
|
|
345
363
|
}
|
package/frontend/js/app.js
CHANGED
|
@@ -56,7 +56,10 @@ import {
|
|
|
56
56
|
openDeleteQueryHistoryModal,
|
|
57
57
|
openDeleteSettingsApiTokenModal,
|
|
58
58
|
openCreateBackupModal,
|
|
59
|
-
|
|
59
|
+
openEditBackupModal,
|
|
60
|
+
openBackupDiffDrawer,
|
|
61
|
+
closeBackupDiffDrawer,
|
|
62
|
+
openGenerateTypesModal,
|
|
60
63
|
openDeleteBackupModal,
|
|
61
64
|
openRestoreBackupModal,
|
|
62
65
|
openDeleteQueryChartModal,
|
|
@@ -122,7 +125,7 @@ import {
|
|
|
122
125
|
submitDeleteSettingsApiTokenConfirmation,
|
|
123
126
|
submitBackupSafetyChoice,
|
|
124
127
|
submitCreateBackupConfirmation,
|
|
125
|
-
|
|
128
|
+
submitEditBackupConfirmation,
|
|
126
129
|
submitRowUpdatePreviewConfirmation,
|
|
127
130
|
setQueryHistoryPanelVisibility,
|
|
128
131
|
sortDataTableByColumn,
|
|
@@ -132,6 +135,7 @@ import {
|
|
|
132
135
|
setCopyColumnModalError,
|
|
133
136
|
setCopyColumnModalEditedText,
|
|
134
137
|
setCopyColumnModalSubmitting,
|
|
138
|
+
setBackupDiffTab,
|
|
135
139
|
setRoute,
|
|
136
140
|
setSettingsSection,
|
|
137
141
|
saveQueryHistoryNotes,
|
|
@@ -166,6 +170,7 @@ import {
|
|
|
166
170
|
updateCurrentTableDesignerColumnField,
|
|
167
171
|
updateCurrentTableDesignerConstraintField,
|
|
168
172
|
updateCurrentTableDesignerField,
|
|
173
|
+
updateGenerateTypesModal,
|
|
169
174
|
addCurrentTableDesignerColumn,
|
|
170
175
|
applyCurrentMediaTaggingSelection,
|
|
171
176
|
removeCurrentTableDesignerColumn,
|
|
@@ -1065,11 +1070,11 @@ function renderNotFoundView() {
|
|
|
1065
1070
|
<p class="font-mono text-[10px] uppercase tracking-[0.3em] text-primary-container/40">
|
|
1066
1071
|
ROUTE_LOST // HASH_NOT_RECOGNIZED
|
|
1067
1072
|
</p>
|
|
1068
|
-
<h1 class="mt-4 font-
|
|
1073
|
+
<h1 class="mt-4 font-body text-6xl font-black uppercase tracking-tight text-primary-container">
|
|
1069
1074
|
404_SIGNAL
|
|
1070
1075
|
</h1>
|
|
1071
1076
|
<button
|
|
1072
|
-
class="standard-button mt-8 px-6 font-
|
|
1077
|
+
class="standard-button mt-8 px-6 font-body text-sm"
|
|
1073
1078
|
data-action="navigate"
|
|
1074
1079
|
data-to="/"
|
|
1075
1080
|
type="button"
|
|
@@ -2003,6 +2008,68 @@ function downloadTextFile({ text, filename, mimeType }) {
|
|
|
2003
2008
|
URL.revokeObjectURL(url);
|
|
2004
2009
|
}
|
|
2005
2010
|
|
|
2011
|
+
async function copyGeneratedTypes() {
|
|
2012
|
+
const modal = getState().modal;
|
|
2013
|
+
const code = modal?.kind === 'generate-types' ? String(modal.result?.code ?? '') : '';
|
|
2014
|
+
|
|
2015
|
+
if (!code) {
|
|
2016
|
+
showToast('No generated code to copy.', 'alert');
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
if (!navigator.clipboard?.writeText) {
|
|
2021
|
+
showToast('Clipboard API is not available.', 'alert');
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
try {
|
|
2026
|
+
await navigator.clipboard.writeText(code);
|
|
2027
|
+
showToast(
|
|
2028
|
+
modal.result?.files?.length ? 'Type definitions copied to clipboard.' : 'Type definition copied to clipboard.',
|
|
2029
|
+
'success',
|
|
2030
|
+
);
|
|
2031
|
+
} catch (error) {
|
|
2032
|
+
showToast(
|
|
2033
|
+
modal.result?.files?.length
|
|
2034
|
+
? 'Type definitions could not be copied.'
|
|
2035
|
+
: 'Type definition could not be copied.',
|
|
2036
|
+
'alert',
|
|
2037
|
+
);
|
|
2038
|
+
}
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
function downloadGeneratedTypes() {
|
|
2042
|
+
const modal = getState().modal;
|
|
2043
|
+
const result = modal?.kind === 'generate-types' ? modal.result : null;
|
|
2044
|
+
const files = result?.files ?? [];
|
|
2045
|
+
|
|
2046
|
+
if (files.length) {
|
|
2047
|
+
files.forEach((file, index) => {
|
|
2048
|
+
window.setTimeout(() => {
|
|
2049
|
+
downloadTextFile({
|
|
2050
|
+
text: file.code,
|
|
2051
|
+
filename: file.fileName || `${file.tableName || 'types'}.txt`,
|
|
2052
|
+
mimeType: 'text/plain;charset=utf-8',
|
|
2053
|
+
});
|
|
2054
|
+
}, index * 120);
|
|
2055
|
+
});
|
|
2056
|
+
showToast(`${files.length} type definition downloads started.`, 'success');
|
|
2057
|
+
return;
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
if (!result?.code) {
|
|
2061
|
+
showToast('No generated code to download.', 'alert');
|
|
2062
|
+
return;
|
|
2063
|
+
}
|
|
2064
|
+
|
|
2065
|
+
downloadTextFile({
|
|
2066
|
+
text: result.code,
|
|
2067
|
+
filename: result.fileName || 'types.txt',
|
|
2068
|
+
mimeType: 'text/plain;charset=utf-8',
|
|
2069
|
+
});
|
|
2070
|
+
showToast('Type definition download started.', 'success');
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2006
2073
|
function getSelectedDataBrowserRowForJson(state) {
|
|
2007
2074
|
if (state.dataBrowser.selectedRow) {
|
|
2008
2075
|
return state.dataBrowser.selectedRow;
|
|
@@ -2582,11 +2649,29 @@ async function handleAction(actionNode) {
|
|
|
2582
2649
|
case 'open-table-in-sql-editor':
|
|
2583
2650
|
await openTableInSqlEditor(actionNode.dataset.tableName);
|
|
2584
2651
|
return;
|
|
2652
|
+
case 'open-generate-types-modal':
|
|
2653
|
+
await openGenerateTypesModal(actionNode.dataset.tableName, actionNode.dataset.typeTarget, actionNode.dataset.typeScope);
|
|
2654
|
+
return;
|
|
2655
|
+
case 'copy-generated-types':
|
|
2656
|
+
await copyGeneratedTypes();
|
|
2657
|
+
return;
|
|
2658
|
+
case 'download-generated-types':
|
|
2659
|
+
downloadGeneratedTypes();
|
|
2660
|
+
return;
|
|
2585
2661
|
case 'open-restore-backup-modal':
|
|
2586
2662
|
openRestoreBackupModal(actionNode.dataset.backupId);
|
|
2587
2663
|
return;
|
|
2588
|
-
case 'open-
|
|
2589
|
-
|
|
2664
|
+
case 'open-compare-backup-drawer':
|
|
2665
|
+
await openBackupDiffDrawer(actionNode.dataset.backupId);
|
|
2666
|
+
return;
|
|
2667
|
+
case 'set-backup-diff-tab':
|
|
2668
|
+
setBackupDiffTab(actionNode.dataset.tab);
|
|
2669
|
+
return;
|
|
2670
|
+
case 'close-backup-diff-drawer':
|
|
2671
|
+
closeBackupDiffDrawer();
|
|
2672
|
+
return;
|
|
2673
|
+
case 'open-edit-backup-modal':
|
|
2674
|
+
openEditBackupModal(actionNode.dataset.backupId);
|
|
2590
2675
|
return;
|
|
2591
2676
|
case 'open-delete-backup-modal':
|
|
2592
2677
|
openDeleteBackupModal(actionNode.dataset.backupId);
|
|
@@ -3181,6 +3266,12 @@ document.addEventListener('keydown', event => {
|
|
|
3181
3266
|
return;
|
|
3182
3267
|
}
|
|
3183
3268
|
|
|
3269
|
+
if (state.route.name === 'backups' && state.backups.diff?.visible) {
|
|
3270
|
+
event.preventDefault();
|
|
3271
|
+
closeBackupDiffDrawer();
|
|
3272
|
+
return;
|
|
3273
|
+
}
|
|
3274
|
+
|
|
3184
3275
|
if (state.editor.historySelectedId !== null || state.editor.historyDetail) {
|
|
3185
3276
|
event.preventDefault();
|
|
3186
3277
|
clearQueryHistorySelection();
|
|
@@ -3227,6 +3318,15 @@ document.addEventListener('input', event => {
|
|
|
3227
3318
|
return;
|
|
3228
3319
|
}
|
|
3229
3320
|
|
|
3321
|
+
if (bindNode.dataset.bind === 'type-generation-field') {
|
|
3322
|
+
if (bindNode instanceof HTMLInputElement && bindNode.type === 'checkbox') {
|
|
3323
|
+
return;
|
|
3324
|
+
}
|
|
3325
|
+
|
|
3326
|
+
void updateGenerateTypesModal(bindNode.dataset.typeGenerationField, bindNode.value);
|
|
3327
|
+
return;
|
|
3328
|
+
}
|
|
3329
|
+
|
|
3230
3330
|
if (bindNode.dataset.bind === 'copy-column-format-field') {
|
|
3231
3331
|
updateCopyColumnModalFormatField(
|
|
3232
3332
|
bindNode.dataset.field,
|
|
@@ -3398,6 +3498,13 @@ document.addEventListener('change', event => {
|
|
|
3398
3498
|
return;
|
|
3399
3499
|
}
|
|
3400
3500
|
|
|
3501
|
+
if (bindNode.dataset.bind === 'type-generation-field') {
|
|
3502
|
+
const nextValue =
|
|
3503
|
+
bindNode instanceof HTMLInputElement && bindNode.type === 'checkbox' ? bindNode.checked : bindNode.value;
|
|
3504
|
+
void updateGenerateTypesModal(bindNode.dataset.typeGenerationField, nextValue);
|
|
3505
|
+
return;
|
|
3506
|
+
}
|
|
3507
|
+
|
|
3401
3508
|
if (bindNode.dataset.bind === 'data-search-column') {
|
|
3402
3509
|
void setDataSearchColumn(bindNode.value);
|
|
3403
3510
|
return;
|
|
@@ -3623,8 +3730,11 @@ document.addEventListener('submit', async event => {
|
|
|
3623
3730
|
type: String(formData.get('type') ?? 'manual'),
|
|
3624
3731
|
});
|
|
3625
3732
|
return;
|
|
3626
|
-
case 'edit-backup
|
|
3627
|
-
await
|
|
3733
|
+
case 'edit-backup':
|
|
3734
|
+
await submitEditBackupConfirmation({
|
|
3735
|
+
name: String(formData.get('name') ?? ''),
|
|
3736
|
+
notes: String(formData.get('notes') ?? ''),
|
|
3737
|
+
});
|
|
3628
3738
|
return;
|
|
3629
3739
|
case 'delete-backup-confirm':
|
|
3630
3740
|
await submitDeleteBackupConfirmation();
|
|
@@ -36,7 +36,7 @@ export function renderConnectionCard(connection, activeConnectionId) {
|
|
|
36
36
|
renderStatusBadge(isActive ? "ACTIVE" : "RECENT", isActive ? "primary" : "muted"),
|
|
37
37
|
connection.readOnly ? renderStatusBadge("READ_ONLY", "alert") : "",
|
|
38
38
|
"</div></div>",
|
|
39
|
-
'<h3 class="mb-1 font-
|
|
39
|
+
'<h3 class="mb-1 font-body text-xl font-bold uppercase ',
|
|
40
40
|
isActive ? "text-[#FCE300]" : "text-on-surface",
|
|
41
41
|
'">',
|
|
42
42
|
escapeHtml(connection.label),
|
|
@@ -61,7 +61,7 @@ function renderActiveConnection(activeConnection) {
|
|
|
61
61
|
<p class="text-[10px] font-mono uppercase tracking-[0.24em] text-primary-container/70">
|
|
62
62
|
ACTIVE_DATABASE
|
|
63
63
|
</p>
|
|
64
|
-
<h2 class="mt-2 font-
|
|
64
|
+
<h2 class="mt-2 font-body text-2xl font-black uppercase tracking-tight text-primary-container">
|
|
65
65
|
${escapeHtml(activeConnection.label)}
|
|
66
66
|
</h2>
|
|
67
67
|
<p class="mt-2 font-mono text-[10px] text-on-surface-variant/55">${escapeHtml(
|
|
@@ -93,7 +93,7 @@ export function renderEmptyState({ activeConnection, recentConnections = [] }) {
|
|
|
93
93
|
SYSTEM_READY // ${hasActive ? 'ACTIVE_CONTEXT' : 'IDLE_STATE'}
|
|
94
94
|
</span>
|
|
95
95
|
</div>
|
|
96
|
-
<h1 class="mb-4 font-
|
|
96
|
+
<h1 class="mb-4 font-body text-7xl font-black tracking-tighter text-primary-container opacity-90 md:text-9xl">
|
|
97
97
|
SQLite Hub
|
|
98
98
|
</h1>
|
|
99
99
|
<p class="font-mono text-primary-container/40">The only fucking SQLite Manager you'll ever need.</p>
|
|
@@ -104,7 +104,7 @@ export function renderEmptyState({ activeConnection, recentConnections = [] }) {
|
|
|
104
104
|
</div>
|
|
105
105
|
<div class="mx-auto grid w-full max-w-3xl grid-cols-1 gap-4 px-6 md:grid-cols-2">
|
|
106
106
|
<button
|
|
107
|
-
class="landing-primary-action clipped-btn group flex items-center justify-between bg-primary-container px-8 py-6 font-
|
|
107
|
+
class="landing-primary-action clipped-btn group flex items-center justify-between bg-primary-container px-8 py-6 font-body text-lg font-bold transition-all duration-300 hover:shadow-[0_0_20px_rgba(252,227,0,0.3)]"
|
|
108
108
|
data-action="open-modal"
|
|
109
109
|
data-modal="open-connection"
|
|
110
110
|
style="--clip-path: polygon(0 0, 90% 0, 100% 25%, 100% 100%, 0 100%);"
|
|
@@ -114,7 +114,7 @@ export function renderEmptyState({ activeConnection, recentConnections = [] }) {
|
|
|
114
114
|
<span class="material-symbols-outlined transition-transform group-hover:translate-x-1">add_circle</span>
|
|
115
115
|
</button>
|
|
116
116
|
<button
|
|
117
|
-
class="flex items-center justify-between border-l-2 border-primary-container bg-surface-container-highest px-8 py-6 font-
|
|
117
|
+
class="flex items-center justify-between border-l-2 border-primary-container bg-surface-container-highest px-8 py-6 font-body text-lg font-bold text-primary-container transition-colors duration-150 hover:bg-surface-bright"
|
|
118
118
|
data-action="open-modal"
|
|
119
119
|
data-modal="create-connection"
|
|
120
120
|
type="button"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { renderDropdownButton } from './dropdownButton.js';
|
|
2
|
+
|
|
3
|
+
export function renderGenerateTypesDropdown({ selectedTableName = '', hasTables = false } = {}) {
|
|
4
|
+
const hasSelectedTable = Boolean(String(selectedTableName ?? '').trim());
|
|
5
|
+
|
|
6
|
+
return renderDropdownButton({
|
|
7
|
+
align: 'left',
|
|
8
|
+
icon: 'code',
|
|
9
|
+
label: 'Generate Types',
|
|
10
|
+
title: 'Generate types',
|
|
11
|
+
items: [
|
|
12
|
+
{
|
|
13
|
+
action: 'open-generate-types-modal',
|
|
14
|
+
disabled: !hasSelectedTable,
|
|
15
|
+
icon: 'select_check_box',
|
|
16
|
+
label: 'Selected table',
|
|
17
|
+
dataAttributes: {
|
|
18
|
+
tableName: selectedTableName,
|
|
19
|
+
typeScope: 'selected',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
action: 'open-generate-types-modal',
|
|
24
|
+
disabled: !hasTables,
|
|
25
|
+
icon: 'library_books',
|
|
26
|
+
label: 'All tables',
|
|
27
|
+
dataAttributes: {
|
|
28
|
+
typeScope: 'all',
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -10,7 +10,7 @@ export function renderMetricCard({
|
|
|
10
10
|
return `
|
|
11
11
|
<div class="metric-card ${accent ? "metric-card--accent" : ""}">
|
|
12
12
|
<span class="text-[10px] font-mono text-on-surface/40 uppercase">${escapeHtml(label)}</span>
|
|
13
|
-
<span class="text-3xl font-
|
|
13
|
+
<span class="text-3xl font-body font-bold text-on-surface">${escapeHtml(value)}</span>
|
|
14
14
|
${
|
|
15
15
|
progress
|
|
16
16
|
? `
|