aboutsummaryrefslogtreecommitdiffstats
path: root/ui/src/state
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/state')
-rw-r--r--ui/src/state/runbooks/runbook.ts124
-rw-r--r--ui/src/state/store.ts17
2 files changed, 141 insertions, 0 deletions
diff --git a/ui/src/state/runbooks/runbook.ts b/ui/src/state/runbooks/runbook.ts
new file mode 100644
index 00000000..8555f4ea
--- /dev/null
+++ b/ui/src/state/runbooks/runbook.ts
@@ -0,0 +1,124 @@
+import Database from "@tauri-apps/plugin-sql";
+import { uuidv7 } from "uuidv7";
+
+export default class Runbook {
+ id: string;
+ created: Date;
+ updated: Date;
+
+ private _name: string;
+ private _content: string;
+
+ set name(value: string) {
+ this.updated = new Date();
+ this._name = value;
+ }
+
+ set content(value: string) {
+ this.updated = new Date();
+ this._content = value;
+ }
+
+ get content() {
+ return this._content;
+ }
+
+ get name() {
+ return this._name;
+ }
+
+ constructor(
+ id: string,
+ name: string,
+ content: string,
+ created: Date,
+ updated: Date,
+ ) {
+ this.id = id;
+ this._name = name;
+ this._content = content;
+ this.created = created;
+ this.updated = updated;
+ }
+
+ /// Create a new Runbook, and automatically generate an ID.
+ public static async create(): Promise<Runbook> {
+ let now = new Date();
+
+ // Initialize with the same value for created/updated, to avoid needing null.
+ let runbook = new Runbook(uuidv7(), "", "", now, now);
+ await runbook.save();
+
+ return runbook;
+ }
+
+ public static async load(id: String): Promise<Runbook | null> {
+ const db = await Database.load("sqlite:runbooks.db");
+
+ let res = await db.select<any[]>("select * from runbooks where id = $1", [
+ id,
+ ]);
+
+ if (res.length == 0) return null;
+
+ let rb = res[0];
+
+ return new Runbook(
+ rb.id,
+ rb.name,
+ rb.content,
+ new Date(rb.created / 1000000),
+ new Date(rb.updated / 1000000),
+ );
+ }
+
+ static async all(): Promise<Runbook[]> {
+ const db = await Database.load("sqlite:runbooks.db");
+
+ let res = await db.select<any[]>(
+ "select * from runbooks order by updated desc",
+ );
+
+ return res.map((i) => {
+ return new Runbook(
+ i.id,
+ i.name,
+ i.content,
+ new Date(i.created / 1000000),
+ new Date(i.updated / 1000000),
+ );
+ });
+ }
+
+ public async save() {
+ const db = await Database.load("sqlite:runbooks.db");
+
+ await db.execute(
+ `insert into runbooks(id, name, content, created, updated)
+ values ($1, $2, $3, $4, $5)
+
+ on conflict(id) do update
+ set
+ name=$2,
+ content=$3,
+ updated=$5`,
+
+ // getTime returns a timestamp as unix milliseconds
+ // we won't need or use the resolution here, but elsewhere Atuin stores timestamps in sqlite as nanoseconds since epoch
+ // let's do that across the board to avoid mistakes
+ [
+ this.id,
+ this._name,
+ this._content,
+ this.created.getTime() * 1000000,
+ this.updated.getTime() * 1000000,
+ ],
+ );
+ }
+
+ public static async delete(id: string) {
+ const db = await Database.load("sqlite:runbooks.db");
+
+ await db.execute("delete from runbooks where id=$1", [id]);
+ }
+}
diff --git a/ui/src/state/store.ts b/ui/src/state/store.ts
index 1e835cbd..cde2da17 100644
--- a/ui/src/state/store.ts
+++ b/ui/src/state/store.ts
@@ -18,6 +18,7 @@ import {
import { invoke } from "@tauri-apps/api/core";
import { sessionToken, settings } from "./client";
import { getWeekInfo } from "@/lib/utils";
+import Runbook from "./runbooks/runbook";
// I'll probs want to slice this up at some point, but for now a
// big blobby lump of state is fine.
@@ -30,14 +31,19 @@ interface AtuinState {
shellHistory: ShellHistory[];
calendar: any[];
weekStart: number;
+ runbooks: Runbook[];
+ currentRunbook: String | null;
refreshHomeInfo: () => void;
refreshCalendar: () => void;
refreshAliases: () => void;
refreshVars: () => void;
refreshUser: () => void;
+ refreshRunbooks: () => void;
refreshShellHistory: (query?: string) => void;
historyNextPage: (query?: string) => void;
+
+ setCurrentRunbook: (id: String) => void;
}
let state = (set: any, get: any): AtuinState => ({
@@ -47,6 +53,8 @@ let state = (set: any, get: any): AtuinState => ({
vars: [],
shellHistory: [],
calendar: [],
+ runbooks: [],
+ currentRunbook: "",
weekStart: getWeekInfo().firstDay,
@@ -68,6 +76,11 @@ let state = (set: any, get: any): AtuinState => ({
});
},
+ refreshRunbooks: async () => {
+ let runbooks = await Runbook.all();
+ set({ runbooks });
+ },
+
refreshShellHistory: (query?: string) => {
if (query) {
invoke("search", { query: query })
@@ -141,6 +154,10 @@ let state = (set: any, get: any): AtuinState => ({
});
}
},
+
+ setCurrentRunbook: (id: String) => {
+ set({ currentRunbook: id });
+ },
});
export const useStore = create<AtuinState>()(