aboutsummaryrefslogtreecommitdiffstats
path: root/ui/src/pages
diff options
context:
space:
mode:
Diffstat (limited to 'ui/src/pages')
-rw-r--r--ui/src/pages/Dotfiles.tsx109
-rw-r--r--ui/src/pages/History.tsx73
-rw-r--r--ui/src/pages/Home.tsx295
-rw-r--r--ui/src/pages/Runbooks.tsx25
4 files changed, 0 insertions, 502 deletions
diff --git a/ui/src/pages/Dotfiles.tsx b/ui/src/pages/Dotfiles.tsx
deleted file mode 100644
index 85f5b0e0..00000000
--- a/ui/src/pages/Dotfiles.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import { useState } from "react";
-import Aliases from "@/components/dotfiles/Aliases";
-import Vars from "@/components/dotfiles/Vars";
-
-enum Section {
- Aliases,
- Vars,
- Snippets,
-}
-
-function renderDotfiles(current: Section) {
- switch (current) {
- case Section.Aliases:
- return <Aliases />;
- case Section.Vars:
- return <Vars />;
- case Section.Snippets:
- return <div />;
- }
-}
-
-interface HeaderProps {
- current: Section;
- setCurrent: (section: Section) => void;
-}
-
-interface TabsProps {
- current: Section;
- setCurrent: (section: Section) => void;
-}
-
-function Header({ current, setCurrent }: HeaderProps) {
- return (
- <div className="md:flex md:items-center md:justify-between">
- <div className="min-w-0 flex-1">
- <h2 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
- Dotfiles
- </h2>
- </div>
-
- <Tabs current={current} setCurrent={setCurrent} />
- </div>
- );
-}
-
-function classNames(...classes: any[]) {
- return classes.filter(Boolean).join(" ");
-}
-
-function Tabs({ current, setCurrent }: TabsProps) {
- let tabs = [
- {
- name: "Aliases",
- isCurrent: () => current === Section.Aliases,
- section: Section.Aliases,
- },
- {
- name: "Vars",
- isCurrent: () => current === Section.Vars,
- section: Section.Vars,
- },
- {
- name: "Snippets",
- isCurrent: () => current === Section.Snippets,
- section: Section.Snippets,
- },
- ];
-
- return (
- <div>
- <div>
- <nav className="flex space-x-4" aria-label="Tabs">
- {tabs.map((tab) => (
- <button
- onClick={() => {
- setCurrent(tab.section);
- }}
- key={tab.name}
- className={classNames(
- tab.isCurrent()
- ? "bg-gray-100 text-gray-700"
- : "text-gray-500 hover:text-gray-700",
- "rounded-md px-3 py-2 text-sm font-medium",
- )}
- aria-current={tab.isCurrent() ? "page" : undefined}
- >
- {tab.name}
- </button>
- ))}
- </nav>
- </div>
- </div>
- );
-}
-
-export default function Dotfiles() {
- let [current, setCurrent] = useState(Section.Aliases);
- console.log(current);
-
- return (
- <div className="w-full flex-1 flex-col p-4 overflow-y-auto">
- <div className="p-10">
- <Header current={current} setCurrent={setCurrent} />
- Manage your shell aliases, variables and paths
- {renderDotfiles(current)}
- </div>
- </div>
- );
-}
diff --git a/ui/src/pages/History.tsx b/ui/src/pages/History.tsx
deleted file mode 100644
index 32f5217e..00000000
--- a/ui/src/pages/History.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { useEffect, useState, useRef } from "react";
-import { useVirtualizer } from "@tanstack/react-virtual";
-
-import HistoryList from "@/components/HistoryList.tsx";
-import HistorySearch from "@/components/HistorySearch.tsx";
-
-import { AtuinState, useStore } from "@/state/store";
-
-export default function Search() {
- const history = useStore((state: AtuinState) => state.shellHistory);
- const refreshHistory = useStore(
- (state: AtuinState) => state.refreshShellHistory,
- );
- const historyNextPage = useStore(
- (state: AtuinState) => state.historyNextPage,
- );
-
- let [query, setQuery] = useState("");
-
- useEffect(() => {
- (async () => {
- // nothing rn
- })();
-
- refreshHistory();
- }, []);
-
- const parentRef = useRef<HTMLElement | null>(null);
-
- const rowVirtualizer = useVirtualizer({
- count: history.length,
- getScrollElement: () => parentRef.current,
- estimateSize: () => 90,
- overscan: 5,
- });
-
- useEffect(() => {
- const [lastItem] = rowVirtualizer.getVirtualItems().slice(-1);
-
- if (!lastItem) return; // no undefined plz
- if (lastItem.index < history.length - 1) return; // if we're not at the end yet, bail
-
- // we're at the end! more rows plz!
- historyNextPage(query);
- }, [rowVirtualizer.getVirtualItems()]);
-
- return (
- <>
- <div className="w-full flex-1 flex-col">
- <div className="flex h-16 shrink-0 items-center gap-x-4 border-b border-t border-gray-200 bg-white px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8 history-search">
- <HistorySearch
- query={query}
- setQuery={(q) => {
- setQuery(q);
- refreshHistory(q);
- }}
- refresh={() => {
- refreshHistory(query);
- }}
- />
- </div>
-
- <main className="overflow-y-scroll history-list" ref={parentRef}>
- <HistoryList
- history={history}
- items={rowVirtualizer.getVirtualItems()}
- height={rowVirtualizer.getTotalSize()}
- />
- </main>
- </div>
- </>
- );
-}
diff --git a/ui/src/pages/Home.tsx b/ui/src/pages/Home.tsx
deleted file mode 100644
index 2e93a893..00000000
--- a/ui/src/pages/Home.tsx
+++ /dev/null
@@ -1,295 +0,0 @@
-import React, { useEffect } from "react";
-import { formatRelative } from "date-fns";
-import { Tooltip as ReactTooltip } from "react-tooltip";
-
-import { AtuinState, useStore } from "@/state/store";
-import { useToast } from "@/components/ui/use-toast";
-import { ToastAction } from "@/components/ui/toast";
-import { invoke } from "@tauri-apps/api/core";
-import {
- Card,
- CardHeader,
- CardBody,
- Listbox,
- ListboxItem,
-} from "@nextui-org/react";
-
-import {
- Bar,
- BarChart,
- CartesianGrid,
- LabelList,
- XAxis,
- YAxis,
-} from "recharts";
-import { ChartConfig, ChartContainer } from "@/components/ui/chart";
-
-import { Clock, Terminal } from "lucide-react";
-
-import ActivityCalendar from "react-activity-calendar";
-import HistoryRow from "@/components/history/HistoryRow";
-import { ShellHistory } from "@/state/models";
-
-function StatCard({ name, stat }: any) {
- return (
- <Card shadow="sm">
- <CardHeader>
- <h3 className="uppercase text-gray-500">{name}</h3>
- </CardHeader>
- <CardBody>
- <h2 className="font-bold text-xl">{stat}</h2>
- </CardBody>
- </Card>
- );
-}
-
-function TopChart({ chartData }: any) {
- const chartConfig = {
- command: {
- label: "Command",
- color: "#c4edde",
- },
- } satisfies ChartConfig;
-
- return (
- <ChartContainer config={chartConfig} className="max-h-72">
- <BarChart
- accessibilityLayer
- data={chartData}
- layout="vertical"
- margin={{
- right: 16,
- }}
- >
- <CartesianGrid horizontal={false} />
- <YAxis
- dataKey="command"
- type="category"
- tickLine={false}
- tickMargin={10}
- axisLine={false}
- tickFormatter={(value) => value.slice(0, 3)}
- hide
- />
- <XAxis dataKey="count" type="number" hide />
- <Bar dataKey="count" layout="vertical" fill="#c4edde" radius={4}>
- <LabelList
- dataKey="command"
- position="insideLeft"
- offset={8}
- className="fill-[--color-label]"
- fontSize={12}
- />
- <LabelList
- dataKey="count"
- position="right"
- offset={8}
- className="fill-foreground"
- fontSize={12}
- />
- </Bar>
- </BarChart>
- </ChartContainer>
- );
-}
-
-function Header({ name }: any) {
- let greeting = name && name.length > 0 ? "Hey, " + name + "!" : "Hey!";
-
- return (
- <div className="md:flex md:items-center md:justify-between">
- <div className="flex-1">
- <h2 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
- {greeting}
- </h2>
- <h3 className="text-xl leading-7 text-gray-900 pt-4">
- Welcome to{" "}
- <a
- href="https://atuin.sh"
- target="_blank"
- rel="noopener noreferrer nofollow"
- >
- Atuin
- </a>
- .
- </h3>
- </div>
- </div>
- );
-}
-
-const explicitTheme = {
- light: ["#f0f0f0", "#c4edde", "#7ac7c4", "#f73859", "#384259"],
- dark: ["#f0f0f0", "#c4edde", "#7ac7c4", "#f73859", "#384259"],
-};
-
-export default function Home() {
- const homeInfo = useStore((state: AtuinState) => state.homeInfo);
- const user = useStore((state: AtuinState) => state.user);
- const calendar = useStore((state: AtuinState) => state.calendar);
- const runbooks = useStore((state: AtuinState) => state.runbooks);
- const weekStart = useStore((state: AtuinState) => state.weekStart);
-
- const refreshHomeInfo = useStore(
- (state: AtuinState) => state.refreshHomeInfo,
- );
- const refreshUser = useStore((state: AtuinState) => state.refreshUser);
- const refreshCalendar = useStore(
- (state: AtuinState) => state.refreshCalendar,
- );
- const refreshRunbooks = useStore(
- (state: AtuinState) => state.refreshRunbooks,
- );
-
- const { toast } = useToast();
-
- useEffect(() => {
- refreshHomeInfo();
- refreshUser();
- refreshCalendar();
- refreshRunbooks();
-
- console.log(homeInfo);
-
- let setup = async () => {
- let installed = await invoke("is_cli_installed");
- console.log("CLI installation status:", installed);
-
- if (!installed) {
- toast({
- title: "Atuin CLI",
- description: "CLI not detected - install?",
- action: (
- <ToastAction
- altText="Install"
- onClick={() => {
- let install = async () => {
- toast({
- title: "Atuin CLI",
- description: "Install in progress...",
- });
-
- console.log("Installing CLI...");
- await invoke("install_cli");
-
- console.log("Setting up plugin...");
- await invoke("setup_cli");
-
- toast({
- title: "Atuin CLI",
- description: "Installation complete",
- });
- };
- install();
- }}
- >
- Install
- </ToastAction>
- ),
- });
- }
- };
-
- setup();
- }, []);
-
- if (!homeInfo) {
- return <div>Loading...</div>;
- }
-
- return (
- <div className="w-full flex-1 flex-col p-4 overflow-y-auto">
- <div className="pl-10">
- <Header name={user.username} />
- </div>
- <div className="p-10 grid grid-cols-4 gap-4">
- <StatCard
- name="Last Sync"
- stat={
- (homeInfo.lastSyncTime &&
- formatRelative(homeInfo.lastSyncTime, new Date())) ||
- "Never"
- }
- />
- <StatCard
- name="Total Commands"
- stat={homeInfo.historyCount.toLocaleString()}
- />
- <StatCard
- name="Total Runbooks"
- stat={runbooks.length.toLocaleString()}
- />
- <StatCard
- name="Other Records"
- stat={homeInfo.recordCount - homeInfo.historyCount}
- />
-
- <Card shadow="sm" className="col-span-3">
- <CardHeader>
- <h2 className="uppercase text-gray-500">Activity graph</h2>
- </CardHeader>
- <CardBody>
- <ActivityCalendar
- hideTotalCount
- theme={explicitTheme}
- data={calendar}
- weekStart={weekStart as any}
- renderBlock={(block, activity) =>
- React.cloneElement(block, {
- "data-tooltip-id": "react-tooltip",
- "data-tooltip-html": `${activity.count} commands on ${activity.date}`,
- })
- }
- />
- <ReactTooltip id="react-tooltip" />
- </CardBody>
- </Card>
-
- <Card shadow="sm">
- <CardHeader>
- <h2 className="uppercase text-gray-500">Quick actions </h2>
- </CardHeader>
-
- <CardBody>
- <Listbox variant="flat" aria-label="Quick actions">
- <ListboxItem
- key="new-runbook"
- description="Create an executable runbook"
- startContent={<Terminal />}
- >
- New runbook
- </ListboxItem>
- <ListboxItem
- key="shell-history"
- description="Search and explore shell history"
- startContent={<Clock />}
- >
- Shell History
- </ListboxItem>
- </Listbox>
- </CardBody>
- </Card>
-
- <Card shadow="sm" className="col-span-2">
- <CardHeader>
- <h2 className="uppercase text-gray-500">Recent commands</h2>
- </CardHeader>
- <CardBody>
- {homeInfo.recentCommands?.map((i: ShellHistory) => {
- return <HistoryRow compact h={i} />;
- })}
- </CardBody>
- </Card>
-
- <Card shadow="sm" className="col-span-2">
- <CardHeader>
- <h2 className="uppercase text-gray-500">Top commands</h2>
- </CardHeader>
- <CardBody>
- <TopChart chartData={homeInfo.topCommands} />
- </CardBody>
- </Card>
- </div>
- </div>
- );
-}
diff --git a/ui/src/pages/Runbooks.tsx b/ui/src/pages/Runbooks.tsx
deleted file mode 100644
index a0b844a6..00000000
--- a/ui/src/pages/Runbooks.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import Editor from "@/components/runbooks/editor/Editor";
-import List from "@/components/runbooks/List";
-
-import { useStore } from "@/state/store";
-
-export default function Runbooks() {
- const currentRunbook = useStore((store) => store.currentRunbook);
-
- return (
- <div className="flex w-full !max-w-full flex-row ">
- <List />
- {currentRunbook && (
- <div className="flex w-full">
- <Editor />
- </div>
- )}
-
- {!currentRunbook && (
- <div className="flex align-middle justify-center flex-col h-screen w-full">
- <h1 className="text-center">Select or create a runbook</h1>
- </div>
- )}
- </div>
- );
-}