mirror of
https://github.com/zadam/trilium.git
synced 2026-02-26 08:33:36 +01:00
chore(sql_console): integrate table reference
This commit is contained in:
parent
476247beb5
commit
4c4e5b85e9
@ -46,7 +46,6 @@ import ScrollPadding from "../widgets/scroll_padding.js";
|
|||||||
import SearchResult from "../widgets/search_result.jsx";
|
import SearchResult from "../widgets/search_result.jsx";
|
||||||
import SharedInfo from "../widgets/shared_info.jsx";
|
import SharedInfo from "../widgets/shared_info.jsx";
|
||||||
import RightPanelContainer from "../widgets/sidebar/RightPanelContainer.jsx";
|
import RightPanelContainer from "../widgets/sidebar/RightPanelContainer.jsx";
|
||||||
import SqlTableSchemas from "../widgets/sql_table_schemas.js";
|
|
||||||
import TabRowWidget from "../widgets/tab_row.js";
|
import TabRowWidget from "../widgets/tab_row.js";
|
||||||
import TabHistoryNavigationButtons from "../widgets/TabHistoryNavigationButtons.jsx";
|
import TabHistoryNavigationButtons from "../widgets/TabHistoryNavigationButtons.jsx";
|
||||||
import TitleBarButtons from "../widgets/title_bar_buttons.jsx";
|
import TitleBarButtons from "../widgets/title_bar_buttons.jsx";
|
||||||
@ -162,7 +161,6 @@ export default class DesktopLayout {
|
|||||||
.child(<SharedInfo />)
|
.child(<SharedInfo />)
|
||||||
)
|
)
|
||||||
.optChild(!isNewLayout, <PromotedAttributes />)
|
.optChild(!isNewLayout, <PromotedAttributes />)
|
||||||
.child(<SqlTableSchemas />)
|
|
||||||
.child(<NoteDetail />)
|
.child(<NoteDetail />)
|
||||||
.child(<NoteList media="screen" />)
|
.child(<NoteList media="screen" />)
|
||||||
.child(<SearchResult />)
|
.child(<SearchResult />)
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +1,31 @@
|
|||||||
import "./SqlConsole.css";
|
import "./SqlConsole.css";
|
||||||
|
|
||||||
import { SqlExecuteResults } from "@triliumnext/commons";
|
import { SchemaResponse, SqlExecuteResults } from "@triliumnext/commons";
|
||||||
import { useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { ClipboardModule, EditModule, ExportModule, FilterModule, FormatModule, FrozenColumnsModule, KeybindingsModule, ResizeColumnsModule, SelectRangeModule, SelectRowModule, SortModule } from "tabulator-tables";
|
import { ClipboardModule, EditModule, ExportModule, FilterModule, FormatModule, FrozenColumnsModule, KeybindingsModule, ResizeColumnsModule, SelectRangeModule, SelectRowModule, SortModule } from "tabulator-tables";
|
||||||
|
|
||||||
import { t } from "../../services/i18n";
|
import { t } from "../../services/i18n";
|
||||||
|
import server from "../../services/server";
|
||||||
import Tabulator from "../collections/table/tabulator";
|
import Tabulator from "../collections/table/tabulator";
|
||||||
import Alert from "../react/Alert";
|
import Alert from "../react/Alert";
|
||||||
|
import Dropdown from "../react/Dropdown";
|
||||||
import { useTriliumEvent } from "../react/hooks";
|
import { useTriliumEvent } from "../react/hooks";
|
||||||
import SplitEditor from "./helpers/SplitEditor";
|
import SplitEditor from "./helpers/SplitEditor";
|
||||||
import { TypeWidgetProps } from "./type_widget";
|
import { TypeWidgetProps } from "./type_widget";
|
||||||
|
|
||||||
export default function SqlConsole(props: TypeWidgetProps) {
|
export default function SqlConsole(props: TypeWidgetProps) {
|
||||||
return (
|
return (
|
||||||
<SplitEditor
|
<>
|
||||||
noteType="code"
|
<SplitEditor
|
||||||
{...props}
|
noteType="code"
|
||||||
previewContent={<SqlResults {...props} />}
|
{...props}
|
||||||
splitOptions={{
|
editorBefore={<SqlTableSchemas {...props} />}
|
||||||
sizes: [ 90, 10 ]
|
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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
|
import "./SplitEditor.css";
|
||||||
|
|
||||||
|
import Split from "@triliumnext/split.js";
|
||||||
|
import { ComponentChildren } from "preact";
|
||||||
import { useEffect, useRef } from "preact/hooks";
|
import { useEffect, useRef } from "preact/hooks";
|
||||||
|
|
||||||
|
import { DEFAULT_GUTTER_SIZE } from "../../../services/resizer";
|
||||||
import utils, { isMobile } from "../../../services/utils";
|
import utils, { isMobile } from "../../../services/utils";
|
||||||
|
import ActionButton, { ActionButtonProps } from "../../react/ActionButton";
|
||||||
import Admonition from "../../react/Admonition";
|
import Admonition from "../../react/Admonition";
|
||||||
import { useNoteLabelBoolean, useTriliumOption } from "../../react/hooks";
|
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 { EditableCode, EditableCodeProps } from "../code/Code";
|
||||||
import { ComponentChildren } from "preact";
|
|
||||||
import ActionButton, { ActionButtonProps } from "../../react/ActionButton";
|
|
||||||
|
|
||||||
export interface SplitEditorProps extends EditableCodeProps {
|
export interface SplitEditorProps extends EditableCodeProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
@ -15,6 +17,7 @@ export interface SplitEditorProps extends EditableCodeProps {
|
|||||||
splitOptions?: Split.Options;
|
splitOptions?: Split.Options;
|
||||||
previewContent: ComponentChildren;
|
previewContent: ComponentChildren;
|
||||||
previewButtons?: ComponentChildren;
|
previewButtons?: ComponentChildren;
|
||||||
|
editorBefore?: ComponentChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,13 +29,14 @@ export interface SplitEditorProps extends EditableCodeProps {
|
|||||||
* - Can display errors to the user via {@link setError}.
|
* - 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.
|
* - 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 splitEditorOrientation = useSplitOrientation();
|
||||||
const [ readOnly ] = useNoteLabelBoolean(note, "readOnly");
|
const [ readOnly ] = useNoteLabelBoolean(note, "readOnly");
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const editor = (!readOnly &&
|
const editor = (!readOnly &&
|
||||||
<div className="note-detail-split-editor-col">
|
<div className="note-detail-split-editor-col">
|
||||||
|
{editorBefore}
|
||||||
<div className="note-detail-split-editor">
|
<div className="note-detail-split-editor">
|
||||||
<EditableCode
|
<EditableCode
|
||||||
note={note}
|
note={note}
|
||||||
@ -74,12 +78,12 @@ export default function SplitEditor({ note, error, splitOptions, previewContent,
|
|||||||
}, [ readOnly, splitEditorOrientation ]);
|
}, [ readOnly, splitEditorOrientation ]);
|
||||||
|
|
||||||
return (
|
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"
|
{splitEditorOrientation === "horizontal"
|
||||||
? <>{editor}{preview}</>
|
? <>{editor}{preview}</>
|
||||||
: <>{preview}{editor}</>}
|
: <>{preview}{editor}</>}
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PreviewButton(props: Omit<ActionButtonProps, "titlePosition">) {
|
export function PreviewButton(props: Omit<ActionButtonProps, "titlePosition">) {
|
||||||
@ -88,7 +92,7 @@ export function PreviewButton(props: Omit<ActionButtonProps, "titlePosition">) {
|
|||||||
className="tn-tool-button"
|
className="tn-tool-button"
|
||||||
noIconActionClass
|
noIconActionClass
|
||||||
titlePosition="top"
|
titlePosition="top"
|
||||||
/>
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function useSplitOrientation() {
|
function useSplitOrientation() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user