sqlite-hub 1.1.0 → 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 +140 -10
- package/frontend/js/components/dropdownButton.js +92 -0
- package/frontend/js/components/modal.js +991 -876
- package/frontend/js/components/queryEditor.js +29 -18
- 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/components/structureGraph.js +1 -0
- package/frontend/js/components/tableDesignerEditor.js +23 -42
- package/frontend/js/components/tableDesignerSidebar.js +7 -31
- package/frontend/js/components/tableDesignerSqlPreview.js +2 -1
- package/frontend/js/router.js +2 -0
- package/frontend/js/store.js +407 -38
- package/frontend/js/utils/riskySql.js +165 -0
- package/frontend/js/views/backups.js +176 -0
- package/frontend/js/views/charts.js +12 -11
- package/frontend/js/views/data.js +37 -35
- package/frontend/js/views/documents.js +231 -162
- package/frontend/js/views/mediaTagging.js +6 -5
- package/frontend/js/views/structure.js +47 -43
- package/frontend/js/views/tableDesigner.js +45 -1
- package/frontend/styles/components.css +237 -59
- package/frontend/styles/structure-graph.css +10 -2
- package/frontend/styles/tailwind.generated.css +1 -1
- package/frontend/styles/tokens.css +2 -0
- package/frontend/styles/views.css +84 -41
- 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/dataBrowserService.js +11 -3
- 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 +38 -3
- 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
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { escapeHtml } from "../utils/format.js";
|
|
2
|
+
|
|
3
|
+
function renderDataAttributes(attributes = {}) {
|
|
4
|
+
return Object.entries(attributes)
|
|
5
|
+
.filter(([, value]) => value !== undefined && value !== null && value !== false)
|
|
6
|
+
.map(([key, value]) => {
|
|
7
|
+
const attributeName = key
|
|
8
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1-$2")
|
|
9
|
+
.replace(/_/g, "-")
|
|
10
|
+
.toLowerCase();
|
|
11
|
+
|
|
12
|
+
return value === true
|
|
13
|
+
? `data-${attributeName}`
|
|
14
|
+
: `data-${attributeName}="${escapeHtml(value)}"`;
|
|
15
|
+
})
|
|
16
|
+
.join(" ");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function renderDropdownItem(item = {}) {
|
|
20
|
+
const dataAttributes = renderDataAttributes(item.dataAttributes);
|
|
21
|
+
const actionAttribute = item.actionAttribute || "data-action";
|
|
22
|
+
const actionMarkup =
|
|
23
|
+
item.action === undefined || item.action === null
|
|
24
|
+
? ""
|
|
25
|
+
: `${escapeHtml(actionAttribute)}="${escapeHtml(item.action)}"`;
|
|
26
|
+
const disabled = item.disabled ? 'disabled aria-disabled="true"' : "";
|
|
27
|
+
const iconMarkup = item.icon
|
|
28
|
+
? `<span class="material-symbols-outlined">${escapeHtml(item.icon)}</span>`
|
|
29
|
+
: "";
|
|
30
|
+
|
|
31
|
+
return `
|
|
32
|
+
<button
|
|
33
|
+
class="dropdown-button__item ${item.danger ? "dropdown-button__item--danger" : ""}"
|
|
34
|
+
${actionMarkup}
|
|
35
|
+
${dataAttributes}
|
|
36
|
+
${disabled}
|
|
37
|
+
role="menuitem"
|
|
38
|
+
type="button"
|
|
39
|
+
>
|
|
40
|
+
${iconMarkup}
|
|
41
|
+
<span>${escapeHtml(item.label)}</span>
|
|
42
|
+
</button>
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function renderDropdownButton({
|
|
47
|
+
align = "right",
|
|
48
|
+
disabled = false,
|
|
49
|
+
icon = "more_horiz",
|
|
50
|
+
items = [],
|
|
51
|
+
label,
|
|
52
|
+
title = label,
|
|
53
|
+
} = {}) {
|
|
54
|
+
const iconMarkup = icon
|
|
55
|
+
? `<span class="material-symbols-outlined">${escapeHtml(icon)}</span>`
|
|
56
|
+
: "";
|
|
57
|
+
const buttonLabel = escapeHtml(label);
|
|
58
|
+
const chevron = '<span class="material-symbols-outlined dropdown-button__chevron">expand_more</span>';
|
|
59
|
+
|
|
60
|
+
if (disabled) {
|
|
61
|
+
return `
|
|
62
|
+
<button
|
|
63
|
+
aria-disabled="true"
|
|
64
|
+
class="standard-button dropdown-button__toggle"
|
|
65
|
+
disabled
|
|
66
|
+
title="${escapeHtml(title)}"
|
|
67
|
+
type="button"
|
|
68
|
+
>
|
|
69
|
+
${iconMarkup}
|
|
70
|
+
${buttonLabel}
|
|
71
|
+
${chevron}
|
|
72
|
+
</button>
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return `
|
|
77
|
+
<details class="dropdown-button dropdown-button--align-${escapeHtml(align)}" data-dropdown-button>
|
|
78
|
+
<summary
|
|
79
|
+
aria-label="${escapeHtml(title)}"
|
|
80
|
+
class="standard-button dropdown-button__toggle"
|
|
81
|
+
title="${escapeHtml(title)}"
|
|
82
|
+
>
|
|
83
|
+
${iconMarkup}
|
|
84
|
+
${buttonLabel}
|
|
85
|
+
${chevron}
|
|
86
|
+
</summary>
|
|
87
|
+
<div class="dropdown-button__panel" role="menu">
|
|
88
|
+
${items.map((item) => renderDropdownItem(item)).join("")}
|
|
89
|
+
</div>
|
|
90
|
+
</details>
|
|
91
|
+
`;
|
|
92
|
+
}
|