Skip to content

Commit

Permalink
improve syntax highlight color and handle error message
Browse files Browse the repository at this point in the history
  • Loading branch information
invisal committed Jan 16, 2025
1 parent 435ce0f commit a8569f7
Show file tree
Hide file tree
Showing 12 changed files with 8,255 additions and 10,977 deletions.
19,121 changes: 8,186 additions & 10,935 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
"oslo": "^1.1.3",
"react": "^18.2.01",
"react-dom": "^18.2.0",
"react-markdown": "^9.0.3",
"react-resizable-panels": "^1.0.9",
"sonner": "^1.4.41",
"sql-formatter": "^15.3.2",
Expand Down
21 changes: 11 additions & 10 deletions src/components/editor/javascript-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,14 @@ function useJavascriptTheme() {
{ tag: [t.bool, t.null], color: "#696C77" },
{ tag: [t.number], color: "#FF0080" },
{ tag: [t.string], color: "#50A14F" },
{ tag: [t.separator], color: "#383A42" },
{ tag: [t.squareBracket], color: "#383A42" },
{ tag: [t.brace], color: "#A626A4" },
],
});
} else {
return createTheme({
theme: "dark",
settings: {
background: "var(--background)",
foreground: "#9cdcfe",
foreground: "#9cdcfd",
caret: "#c6c6c6",
selection: "#6199ff2f",
selectionMatch: "#72a1ff59",
Expand All @@ -64,13 +61,17 @@ function useJavascriptTheme() {
'Consolas, "Andale Mono", "Ubuntu Mono", "Courier New", monospace',
},
styles: [
{ tag: [t.propertyName], color: "#9b59b6" },
{
tag: [t.propertyName, t.function(t.variableName)],
color: "#dcdcaa",
},
{ tag: [t.keyword], color: "#c586c0" },
{ tag: [t.comment, t.blockComment], color: "#95a5a6" },
{ tag: [t.bool, t.null], color: "#696C77" },
{ tag: [t.number], color: "#f39c12" },
{ tag: [t.string], color: "#50A14F" },
{ tag: [t.separator], color: "#383A42" },
{ tag: [t.squareBracket], color: "#383A42" },
{ tag: [t.brace], color: "#A626A4" },
{ tag: [t.number], color: "#b5cea8" },
{ tag: [t.string], color: "#ce9178" },
{ tag: [t.paren], color: "#9cdcfd" },
{ tag: [t.bracket], color: "#da70d6" },
],
});
}
Expand Down
9 changes: 6 additions & 3 deletions src/components/gui/database-gui.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { normalizedPathname, sendAnalyticEvents } from "@/lib/tracking";
import { useConfig } from "@/context/config-provider";
import { cn } from "@/lib/utils";
import { scc } from "@/core/command";
import { StudioExtensionMenuItem } from "@/core/extension-manager";

export default function DatabaseGui() {
const DEFAULT_WIDTH = 300;
Expand Down Expand Up @@ -129,21 +130,23 @@ export default function DatabaseGui() {
const tabSideMenu = useMemo(() => {
return [
{
text: "New Query",
key: "query",
title: "New Query",
onClick: () => {
scc.tabs.openBuiltinQuery({});
},
},
...extensions.getWindowTabMenu(),
databaseDriver.getFlags().supportCreateUpdateTable
? {
text: "New Table",
key: "table",
title: "New Table",
onClick: () => {
scc.tabs.openBuiltinSchema({ schemaName: currentSchemaName });
},
}
: undefined,
].filter(Boolean) as { text: string; onClick: () => void }[];
].filter(Boolean) as StudioExtensionMenuItem[];
}, [currentSchemaName, databaseDriver, extensions]);

// Send to analytic when tab changes.
Expand Down
5 changes: 3 additions & 2 deletions src/components/gui/windows-tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
DropdownMenuTrigger,
} from "../ui/dropdown-menu";
import { restrictToHorizontalAxis } from "../lib/dnd-kit";
import { StudioExtensionMenuItem } from "@/core/extension-manager";

export interface WindowTabItemProps {
component: JSX.Element;
Expand All @@ -41,7 +42,7 @@ export interface WindowTabItemProps {
}

interface WindowTabsProps {
menu?: { text: string; onClick: () => void }[];
menu?: StudioExtensionMenuItem[];
tabs: WindowTabItemProps[];
selected: number;
hideCloseButton?: boolean;
Expand Down Expand Up @@ -254,7 +255,7 @@ export default function WindowTabs({
key={menuIdx}
onClick={menuItem.onClick}
>
{menuItem.text}
{menuItem.title}
</DropdownMenuItem>
);
})}
Expand Down
13 changes: 6 additions & 7 deletions src/core/extension-manager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export class BeforeQueryPipeline {
type BeforeQueryHandler = (payload: BeforeQueryPipeline) => Promise<void>;
type AfterQueryHandler = () => Promise<void>;


export interface StudioExtensionMenuItem {
key: string;
title: string;
Expand All @@ -65,6 +64,7 @@ export class StudioExtensionContext {
protected beforeQueryHandlers: BeforeQueryHandler[] = [];
protected afterQueryHandlers: AfterQueryHandler[] = [];
protected resourceCreateMenu: StudioExtensionMenuItem[] = [];
protected windowTabMenu: StudioExtensionMenuItem[] = [];
protected resourceContextMenu: Record<string, CreateResourceMenuHandler[]> =
{};

Expand All @@ -83,7 +83,6 @@ export class StudioExtensionContext {
}

registerCreateResourceMenu(menu: StudioExtensionMenuItem) {
console.log("Register", menu);
this.resourceCreateMenu.push(menu);
}

Expand All @@ -97,6 +96,10 @@ export class StudioExtensionContext {
this.resourceContextMenu[group].push(handler);
}
}

registerWindowTabMenu(menu: StudioExtensionMenuItem) {
this.windowTabMenu.push(menu);
}
}
export class StudioExtensionManager extends StudioExtensionContext {
init() {
Expand Down Expand Up @@ -124,11 +127,7 @@ export class StudioExtensionManager extends StudioExtensionContext {
.filter(Boolean) as StudioExtensionMenuItem[];
}

registerWindowTabMenu(menu: ExtensionMenuItem) {
this.windowTabMenu.push(menu);
}

getWindowTabMenu(): Readonly<ExtensionMenuItem[]> {
getWindowTabMenu(): Readonly<StudioExtensionMenuItem[]> {
return this.windowTabMenu;
}

Expand Down
6 changes: 5 additions & 1 deletion src/core/standard-extension.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ import QueryHistoryConsoleLogExtension from "@/extensions/query-console-log";
import ViewEditorExtension from "@/extensions/view-editor";

export function createStandardExtensions() {
return [new QueryHistoryConsoleLogExtension(), new ViewEditorExtension()];
return [
new QueryHistoryConsoleLogExtension(),
new ViewEditorExtension(),
new NotebookExtension(),
];
}
5 changes: 3 additions & 2 deletions src/extensions/notebook/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const notebookTab = createTabExtension({
name: "notebook",
key: () => "notebook",
generate: () => ({
title: "Notebook",
title: "New Notebook",
component: <NotebookTab />,
icon: NotebookIcon,
}),
Expand All @@ -19,7 +19,8 @@ export default class NotebookExtension extends StudioExtension {

init(studio: StudioExtensionManager): void {
studio.registerWindowTabMenu({
text: "Notebook",
key: "notebook",
title: "New Notebook",
onClick: () => {
notebookTab.open({});
},
Expand Down
22 changes: 16 additions & 6 deletions src/extensions/notebook/notebook-block-code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { NotebookEditorBlockValue } from "./notebook-editor";
import { NotebookVM } from "./notebook-vm";
import JavascriptEditor from "@/components/editor/javascript-editor";
import { Button } from "@/components/ui/button";
import { PlayIcon, Terminal } from "lucide-react";
import { LucideShieldAlert, PlayIcon, Terminal } from "lucide-react";
import { produce } from "immer";
import { cn } from "@/lib/utils";

interface OutputFormat {
type: "log";
Expand All @@ -30,7 +31,7 @@ function OutputArgItem({ value }: { value: unknown }) {
}

return (value ?? "").toString();
}, []);
}, [value]);

if (content.length > 500) {
return (
Expand All @@ -42,9 +43,18 @@ function OutputArgItem({ value }: { value: unknown }) {
}

function OutputItem({ value }: { value: OutputFormat }) {
const color = value.type === "log" ? "" : "text-red-400 dark:text-red-300";

return (
<div>
<pre>
<div className={cn(color, "flex")}>
{value.type === "log" ? (
<div className="w-7"></div>
) : (
<div className="w-7">
<LucideShieldAlert className="w-5 h-5" />
</div>
)}
<pre className="flex-1">
{value.args.map((argValue, argIndex) => (
<OutputArgItem value={argValue} key={argIndex} />
))}
Expand Down Expand Up @@ -84,7 +94,7 @@ export default function NotebookBlockCode({
};

return (
<div className="flex-1 flex flex-col p-3 gap-2">
<div className="flex-1 flex flex-col gap-2">
<div className="flex gap-2">
<Button variant={"outline"} onClick={onRunClick}>
<PlayIcon className="w-4 h-4 mr-2" /> Run
Expand All @@ -106,7 +116,7 @@ export default function NotebookBlockCode({
}}
/>

<div>
<div className="flex flex-col gap-1">
{output.map((outputContent, outIdx) => (
<OutputItem key={outIdx} value={outputContent} />
))}
Expand Down
7 changes: 3 additions & 4 deletions src/extensions/notebook/notebook-block-md.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { compile } from "@mdx-js/mdx";
import { useEffect, useMemo, useState } from "react";
import Markdown from "react-markdown";
import { NotebookEditorBlockValue } from "./notebook-editor";

export default function NotebookBlockCode({
Expand All @@ -10,8 +9,8 @@ export default function NotebookBlockCode({
onChange: (value: NotebookEditorBlockValue) => void;
}) {
return (
<div className="p-3">
<textarea className="w-full resize-none" value={value.value} readOnly />
<div className="p-3 mdx-content">
<Markdown>{value.value}</Markdown>
</div>
);
}
18 changes: 13 additions & 5 deletions src/extensions/notebook/notebook-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,29 @@ export default function NotebookEditor() {
id: "initial2",
type: "markdown",
value:
`# Hello World` +
`# Hello Notebook` +
"\n" +
`This is the demo notebook editor in Outerbase Studio`,
},
{
id: "initial",
type: "code",
value: `console.log(await query("SELECT 1 + 1"))`,
value: `console.log(b.hello)`,
},
{
id: "initial3",
type: "markdown",
value: `Insert many rows using the power of Javascript`,
},
{
id: "initial4",
type: "code",
value: `for(let i = 0; i < 5; i++) {
await sleep(1000);
console.log("This is loop", i)
const age = Math.floor(Math.random() * 100));
const name = "name \${i}";
await query(\`INSERT INTO testing(name, age) VALUES ('\${name}', \${age})\`);
console.log("Inserting", name, age);
}`,
},
]);
Expand Down Expand Up @@ -76,8 +84,8 @@ export default function NotebookEditor() {
<ToolbarButton text="Restart" />
</Toolbar>
</div>
<div className="flex-1 bg-gray-100 overflow-y-auto p-4">
<div className="max-w-[1200px] bg-background mx-auto">
<div className="flex-1 overflow-y-auto p-4">
<div className="max-w-[1200px] mx-auto">
{value.map((block, idx) => {
if (block.type === "code") {
return (
Expand Down
4 changes: 2 additions & 2 deletions src/extensions/notebook/notebook-vm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const workerCode = `
else queryPromise[e.data.id].resolve(e.data.result);
}
} catch (error) {
self.postMessage({ type: "log", args: [error.toString()] });
self.postMessage({ type: "error", args: [error.toString()] });
self.postMessage({ type: "complete" });
}
};
Expand All @@ -70,7 +70,7 @@ export class NotebookVM {
this.vm.onmessage = (e) => {
const { type } = e.data;

if (type === "log") {
if (type === "log" || type === "error") {
if (this.onStdOut) {
this.onStdOut(e.data);
}
Expand Down

0 comments on commit a8569f7

Please sign in to comment.