chore(sql_console): integrate table reference

This commit is contained in:
Elian Doran 2026-01-17 22:38:18 +02:00
parent 476247beb5
commit 4c4e5b85e9
No known key found for this signature in database
6 changed files with 109 additions and 103 deletions

View File

@ -46,7 +46,6 @@ import ScrollPadding from "../widgets/scroll_padding.js";
import SearchResult from "../widgets/search_result.jsx";
import SharedInfo from "../widgets/shared_info.jsx";
import RightPanelContainer from "../widgets/sidebar/RightPanelContainer.jsx";
import SqlTableSchemas from "../widgets/sql_table_schemas.js";
import TabRowWidget from "../widgets/tab_row.js";
import TabHistoryNavigationButtons from "../widgets/TabHistoryNavigationButtons.jsx";
import TitleBarButtons from "../widgets/title_bar_buttons.jsx";
@ -162,7 +161,6 @@ export default class DesktopLayout {
.child(<SharedInfo />)
)
.optChild(!isNewLayout, <PromotedAttributes />)
.child(<SqlTableSchemas />)
.child(<NoteDetail />)
.child(<NoteList media="screen" />)
.child(<SearchResult />)

View File

@ -1,34 +0,0 @@
.sql-table-schemas-widget {
padding: 12px;
padding-inline-end: 10%;
contain: none !important;
}
.sql-table-schemas > .dropdown {
display: inline-block !important;
}
.sql-table-schemas button.btn {
padding: 0.25rem 0.4rem;
font-size: 0.875rem;
line-height: 0.5;
border: 1px solid var(--button-border-color);
border-radius: var(--button-border-radius);
background: var(--button-background-color);
color: var(--button-text-color);
cursor: pointer;
}
.table-schema td {
padding: 5px;
}
.dropdown .table-schema {
font-family: var(--monospace-font-family);
font-size: .85em;
}
/* Data type */
.dropdown .table-schema td:nth-child(2) {
color: var(--muted-text-color);
}

View File

@ -1,46 +0,0 @@
import { useEffect, useState } from "preact/hooks";
import { t } from "../services/i18n";
import { useNoteContext } from "./react/hooks";
import "./sql_table_schemas.css";
import { SchemaResponse } from "@triliumnext/commons";
import server from "../services/server";
import Dropdown from "./react/Dropdown";
export default function SqlTableSchemas() {
const { note } = useNoteContext();
const [ schemas, setSchemas ] = useState<SchemaResponse[]>();
useEffect(() => {
server.get<SchemaResponse[]>("sql/schema").then(setSchemas);
}, []);
const isEnabled = note?.mime === "text/x-sqlite;schema=trilium" && schemas;
return (
<div className={`sql-table-schemas-widget ${!isEnabled ? "hidden-ext" : ""}`}>
{isEnabled && (
<>
{t("sql_table_schemas.tables")}{": "}
<span class="sql-table-schemas">
{schemas.map(({ name, columns }) => (
<>
<Dropdown text={name} noSelectButtonStyle hideToggleArrow
>
<table className="table-schema">
{columns.map(column => (
<tr>
<td>{column.name}</td>
<td>{column.type}</td>
</tr>
))}
</table>
</Dropdown>
{" "}
</>
))}
</span>
</>
)}
</div>
)
}

View File

@ -32,5 +32,46 @@
}
}
}
.sql-table-schemas-widget {
padding: 12px;
padding-inline-end: 10%;
contain: none !important;
.sql-table-schemas {
display: flex;
flex-wrap: wrap;
gap: 0.25em;
}
> .dropdown {
display: inline-block !important;
}
button.btn {
padding: 0.25rem 0.4rem;
font-size: 0.875rem;
line-height: 0.5;
border: 1px solid var(--button-border-color);
border-radius: var(--button-border-radius);
background: var(--button-background-color);
color: var(--button-text-color);
cursor: pointer;
}
.table-schema td {
padding: 5px;
}
.dropdown .table-schema {
font-family: var(--monospace-font-family);
font-size: .85em;
}
/* Data type */
.dropdown .table-schema td:nth-child(2) {
color: var(--muted-text-color);
}
}
}

View File

@ -1,26 +1,31 @@
import "./SqlConsole.css";
import { SqlExecuteResults } from "@triliumnext/commons";
import { useState } from "preact/hooks";
import { SchemaResponse, SqlExecuteResults } from "@triliumnext/commons";
import { useEffect, useState } from "preact/hooks";
import { ClipboardModule, EditModule, ExportModule, FilterModule, FormatModule, FrozenColumnsModule, KeybindingsModule, ResizeColumnsModule, SelectRangeModule, SelectRowModule, SortModule } from "tabulator-tables";
import { t } from "../../services/i18n";
import server from "../../services/server";
import Tabulator from "../collections/table/tabulator";
import Alert from "../react/Alert";
import Dropdown from "../react/Dropdown";
import { useTriliumEvent } from "../react/hooks";
import SplitEditor from "./helpers/SplitEditor";
import { TypeWidgetProps } from "./type_widget";
export default function SqlConsole(props: TypeWidgetProps) {
return (
<SplitEditor
noteType="code"
{...props}
previewContent={<SqlResults {...props} />}
splitOptions={{
sizes: [ 90, 10 ]
}}
/>
<>
<SplitEditor
noteType="code"
{...props}
editorBefore={<SqlTableSchemas {...props} />}
previewContent={<SqlResults {...props} />}
splitOptions={{
sizes: [ 70, 30 ]
}}
/>
</>
);
}
@ -94,3 +99,41 @@ function SqlResultTable({ rows }: { rows: object[] }) {
/>
);
}
export function SqlTableSchemas({ note }: TypeWidgetProps) {
const [ schemas, setSchemas ] = useState<SchemaResponse[]>();
useEffect(() => {
server.get<SchemaResponse[]>("sql/schema").then(setSchemas);
}, []);
const isEnabled = note?.mime === "text/x-sqlite;schema=trilium" && schemas;
return (
<div className={`sql-table-schemas-widget ${!isEnabled ? "hidden-ext" : ""}`}>
{isEnabled && (
<>
{t("sql_table_schemas.tables")}{": "}
<span class="sql-table-schemas">
{schemas.map(({ name, columns }) => (
<>
<Dropdown text={name} noSelectButtonStyle hideToggleArrow
>
<table className="table-schema">
{columns.map(column => (
<tr>
<td>{column.name}</td>
<td>{column.type}</td>
</tr>
))}
</table>
</Dropdown>
{" "}
</>
))}
</span>
</>
)}
</div>
);
}

View File

@ -1,13 +1,15 @@
import "./SplitEditor.css";
import Split from "@triliumnext/split.js";
import { ComponentChildren } from "preact";
import { useEffect, useRef } from "preact/hooks";
import { DEFAULT_GUTTER_SIZE } from "../../../services/resizer";
import utils, { isMobile } from "../../../services/utils";
import ActionButton, { ActionButtonProps } from "../../react/ActionButton";
import Admonition from "../../react/Admonition";
import { useNoteLabelBoolean, useTriliumOption } from "../../react/hooks";
import "./SplitEditor.css";
import Split from "@triliumnext/split.js";
import { DEFAULT_GUTTER_SIZE } from "../../../services/resizer";
import { EditableCode, EditableCodeProps } from "../code/Code";
import { ComponentChildren } from "preact";
import ActionButton, { ActionButtonProps } from "../../react/ActionButton";
export interface SplitEditorProps extends EditableCodeProps {
className?: string;
@ -15,6 +17,7 @@ export interface SplitEditorProps extends EditableCodeProps {
splitOptions?: Split.Options;
previewContent: ComponentChildren;
previewButtons?: ComponentChildren;
editorBefore?: ComponentChildren;
}
/**
@ -26,13 +29,14 @@ export interface SplitEditorProps extends EditableCodeProps {
* - Can display errors to the user via {@link setError}.
* - Horizontal or vertical orientation for the editor/preview split, adjustable via the switch split orientation button floating button.
*/
export default function SplitEditor({ note, error, splitOptions, previewContent, previewButtons, className, ...editorProps }: SplitEditorProps) {
export default function SplitEditor({ note, error, splitOptions, previewContent, previewButtons, className, editorBefore, ...editorProps }: SplitEditorProps) {
const splitEditorOrientation = useSplitOrientation();
const [ readOnly ] = useNoteLabelBoolean(note, "readOnly");
const containerRef = useRef<HTMLDivElement>(null);
const editor = (!readOnly &&
<div className="note-detail-split-editor-col">
{editorBefore}
<div className="note-detail-split-editor">
<EditableCode
note={note}
@ -74,12 +78,12 @@ export default function SplitEditor({ note, error, splitOptions, previewContent,
}, [ readOnly, splitEditorOrientation ]);
return (
<div ref={containerRef} className={`note-detail-split note-detail-printable ${"split-" + splitEditorOrientation} ${readOnly ? "split-read-only" : ""} ${className ?? ""}`}>
<div ref={containerRef} className={`note-detail-split note-detail-printable ${`split-${ splitEditorOrientation}`} ${readOnly ? "split-read-only" : ""} ${className ?? ""}`}>
{splitEditorOrientation === "horizontal"
? <>{editor}{preview}</>
: <>{preview}{editor}</>}
? <>{editor}{preview}</>
: <>{preview}{editor}</>}
</div>
)
);
}
export function PreviewButton(props: Omit<ActionButtonProps, "titlePosition">) {
@ -88,7 +92,7 @@ export function PreviewButton(props: Omit<ActionButtonProps, "titlePosition">) {
className="tn-tool-button"
noIconActionClass
titlePosition="top"
/>
/>;
}
function useSplitOrientation() {