aboutsummaryrefslogtreecommitdiffstats
path: root/ui/src/components/runbooks
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/components/runbooks')
-rw-r--r--ui/src/components/runbooks/List.tsx15
-rw-r--r--ui/src/components/runbooks/editor/Editor.tsx74
-rw-r--r--ui/src/components/runbooks/editor/blocks/RunBlock/index.tsx20
3 files changed, 63 insertions, 46 deletions
diff --git a/ui/src/components/runbooks/List.tsx b/ui/src/components/runbooks/List.tsx
index 72c1b3b3..024bcfd1 100644
--- a/ui/src/components/runbooks/List.tsx
+++ b/ui/src/components/runbooks/List.tsx
@@ -1,12 +1,7 @@
-import { useEffect, useState } from "react";
+import { useEffect } from "react";
import {
- Input,
Button,
ButtonGroup,
- Card,
- CardBody,
- CardHeader,
- Divider,
Tooltip,
Listbox,
ListboxItem,
@@ -46,13 +41,13 @@ const NoteSidebar = () => {
<div className="overflow-y-auto flex-grow">
<Listbox
hideSelectedIcon
- items={runbooks.map((runbook) => {
+ items={runbooks.map((runbook: any): any => {
return [runbook, runbookInfo[runbook.id]];
})}
variant="flat"
aria-label="Runbook list"
selectionMode="single"
- selectedKeys={[currentRunbook]}
+ selectedKeys={currentRunbook ? [currentRunbook] : []}
itemClasses={{ base: "data-[selected=true]:bg-gray-200" }}
topContent={
<ButtonGroup className="z-20">
@@ -74,7 +69,7 @@ const NoteSidebar = () => {
</ButtonGroup>
}
>
- {([runbook, info]) => (
+ {([runbook, info]: [Runbook, { ptys: number }]) => (
<ListboxItem
key={runbook.id}
onPress={() => {
@@ -124,7 +119,7 @@ const NoteSidebar = () => {
<div className="text-xs text-gray-500">
<em>
{DateTime.fromJSDate(runbook.updated).toLocaleString(
- DateTime.DATETIME_SIMPLE,
+ DateTime.DATETIME_SHORT,
)}
</em>
</div>
diff --git a/ui/src/components/runbooks/editor/Editor.tsx b/ui/src/components/runbooks/editor/Editor.tsx
index 98a6a282..bbf594d8 100644
--- a/ui/src/components/runbooks/editor/Editor.tsx
+++ b/ui/src/components/runbooks/editor/Editor.tsx
@@ -1,37 +1,47 @@
import { useEffect, useMemo, useState } from "react";
-import "@blocknote/core/fonts/inter.css";
-import "@blocknote/mantine/style.css";
import "./index.css";
import { Spinner } from "@nextui-org/react";
+// Errors, but it all works fine and is there. Maybe missing ts defs?
+// I'll figure it out later
import {
+ // @ts-ignore
BlockNoteSchema,
+ // @ts-ignore
BlockNoteEditor,
+ // @ts-ignore
defaultBlockSpecs,
+ // @ts-ignore
filterSuggestionItems,
+ // @ts-ignore
insertOrUpdateBlock,
} from "@blocknote/core";
-import "@blocknote/core/fonts/inter.css";
-
import {
+ //@ts-ignore
SuggestionMenuController,
+ // @ts-ignore
AddBlockButton,
+ // @ts-ignore
getDefaultReactSlashMenuItems,
- useCreateBlockNote,
+ // @ts-ignore
SideMenu,
+ // @ts-ignore
SideMenuController,
} from "@blocknote/react";
import { BlockNoteView } from "@blocknote/mantine";
+import "@blocknote/core/fonts/inter.css";
+import "@blocknote/mantine/style.css";
+
import { Code } from "lucide-react";
import { useDebounceCallback } from "usehooks-ts";
import RunBlock from "@/components/runbooks/editor/blocks/RunBlock";
import { DeleteBlock } from "@/components/runbooks/editor/ui/DeleteBlockButton";
-import { useStore } from "@/state/store";
+import { AtuinState, useStore } from "@/state/store";
import Runbook from "@/state/runbooks/runbook";
// Our schema with block specs, which contain the configs and implementations for blocks
@@ -60,8 +70,10 @@ const insertRun = (editor: typeof schema.BlockNoteEditor) => ({
});
export default function Editor() {
- const runbookId = useStore((store) => store.currentRunbook);
- const refreshRunbooks = useStore((store) => store.refreshRunbooks);
+ const runbookId = useStore((store: AtuinState) => store.currentRunbook);
+ const refreshRunbooks = useStore(
+ (store: AtuinState) => store.refreshRunbooks,
+ );
let [runbook, setRunbook] = useState<Runbook | null>(null);
useEffect(() => {
@@ -76,43 +88,43 @@ export default function Editor() {
fetchRunbook();
}, [runbookId]);
- const editor = useMemo(() => {
- if (!runbook) {
- return undefined;
- }
-
- if (runbook.content) {
- return BlockNoteEditor.create({
- initialContent: JSON.parse(runbook.content),
- schema,
- });
- }
-
- return BlockNoteEditor.create({ schema });
- }, [runbook]);
-
const onChange = async () => {
if (!runbook) return;
console.log("saved!");
runbook.name = fetchName();
- runbook.content = JSON.stringify(editor.document);
+ if (editor) runbook.content = JSON.stringify(editor.document);
await runbook.save();
- await refreshRunbooks();
+ refreshRunbooks();
};
const debouncedOnChange = useDebounceCallback(onChange, 1000);
+ const editor = useMemo(() => {
+ if (!runbook) return undefined;
+ if (runbook.content) {
+ return BlockNoteEditor.create({
+ initialContent: JSON.parse(runbook.content),
+ schema,
+ });
+ }
+
+ return BlockNoteEditor.create({ schema });
+ }, [runbook]);
+
const fetchName = (): string => {
// Infer the title from the first text block
+ if (!editor) return "Untitled";
let blocks = editor.document;
for (const block of blocks) {
if (block.type == "heading" || block.type == "paragraph") {
if (block.content.length == 0) continue;
+ // @ts-ignore
if (block.content[0].text.length == 0) continue;
+ // @ts-ignore
return block.content[0].text;
}
}
@@ -120,6 +132,14 @@ export default function Editor() {
return "Untitled";
};
+ if (!runbook) {
+ return (
+ <div className="flex w-full h-full flex-col justify-center items-center">
+ <Spinner />
+ </div>
+ );
+ }
+
if (editor === undefined) {
return (
<div className="flex w-full h-full flex-col justify-center items-center">
@@ -139,7 +159,7 @@ export default function Editor() {
>
<SuggestionMenuController
triggerCharacter={"/"}
- getItems={async (query) =>
+ getItems={async (query: any) =>
filterSuggestionItems(
[...getDefaultReactSlashMenuItems(editor), insertRun(editor)],
query,
@@ -148,7 +168,7 @@ export default function Editor() {
/>
<SideMenuController
- sideMenu={(props) => (
+ sideMenu={(props: any) => (
<SideMenu {...props}>
<AddBlockButton {...props} />
<DeleteBlock {...props} />
diff --git a/ui/src/components/runbooks/editor/blocks/RunBlock/index.tsx b/ui/src/components/runbooks/editor/blocks/RunBlock/index.tsx
index 15653611..b3a96166 100644
--- a/ui/src/components/runbooks/editor/blocks/RunBlock/index.tsx
+++ b/ui/src/components/runbooks/editor/blocks/RunBlock/index.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+// @ts-ignore
import { createReactBlockSpec } from "@blocknote/react";
import "./index.css";
@@ -48,7 +48,7 @@ const RunBlock = ({
],
);
- const isRunning = pty !== null;
+ const isRunning = pty !== null && pty !== "";
const handleToggle = async (event: any | null) => {
if (event) event.stopPropagation();
@@ -63,21 +63,21 @@ const RunBlock = ({
cleanupPtyTerm(pty);
if (onStop) onStop(pty);
- decRunbookPty(currentRunbook);
+ if (currentRunbook) decRunbookPty(currentRunbook);
}
if (!isRunning) {
let pty = await invoke<string>("pty_open");
if (onRun) onRun(pty);
- incRunbookPty(currentRunbook);
+ if (currentRunbook) incRunbookPty(currentRunbook);
let val = !value.endsWith("\n") ? value + "\r\n" : value;
await invoke("pty_write", { pid: pty, data: val });
}
};
- const handleCmdEnter = (view) => {
+ const handleCmdEnter = () => {
handleToggle(null);
return true;
};
@@ -145,7 +145,7 @@ export default createReactBlockSpec(
default: "bash",
},
code: { default: "" },
- pty: { default: null },
+ pty: { default: "" },
},
content: "none",
},
@@ -154,19 +154,21 @@ export default createReactBlockSpec(
render: ({ block, editor, code, type }) => {
const onInputChange = (val: string) => {
editor.updateBlock(block, {
+ // @ts-ignore
props: { ...block.props, code: val },
});
};
const onRun = (pty: string) => {
editor.updateBlock(block, {
+ // @ts-ignore
props: { ...block.props, pty: pty },
});
};
- const onStop = (pty: string) => {
- editor.updateBlock(block, {
- props: { ...block.props, pty: null },
+ const onStop = (_pty: string) => {
+ editor?.updateBlock(block, {
+ props: { ...block.props, pty: "" },
});
};