diff options
| author | Ellie Huxtable <ellie@atuin.sh> | 2024-07-30 16:54:10 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-30 16:54:10 +0100 |
| commit | 808138de633e410c1d3867d4fb7cb74967647605 (patch) | |
| tree | f180b7066b91d8d8d8006219a118439be1621d74 /ui/src/components/history | |
| parent | chore(deps): bump debian (#2320) (diff) | |
| download | atuin-808138de633e410c1d3867d4fb7cb74967647605.zip | |
chore: remove ui directory (#2329)
This is still in development, but rather than clutter the commit history
and issues with an unreleased project I've split the UI into its own
repo.
Once ready for release, I'll either merge the ui code back in, or just
make the repo public.
Diffstat (limited to 'ui/src/components/history')
| -rw-r--r-- | ui/src/components/history/HistoryInspect.tsx | 40 | ||||
| -rw-r--r-- | ui/src/components/history/HistoryRow.tsx | 120 | ||||
| -rw-r--r-- | ui/src/components/history/Stats.tsx | 161 |
3 files changed, 0 insertions, 321 deletions
diff --git a/ui/src/components/history/HistoryInspect.tsx b/ui/src/components/history/HistoryInspect.tsx deleted file mode 100644 index 6c46f2db..00000000 --- a/ui/src/components/history/HistoryInspect.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { useState, useEffect } from "react"; - -import PacmanLoader from "react-spinners/PacmanLoader"; - -import CodeBlock from "@/components/CodeBlock"; -import HistoryRow from "@/components/history/HistoryRow"; -import { ShellHistory, inspectCommandHistory } from "@/state/models"; - -function renderLoading() { - return ( - <div className="flex items-center justify-center h-full"> - <PacmanLoader color="#26bd65" /> - </div> - ); -} - -export default function HistoryInspect({ history }: any) { - let [other, setOther] = useState<ShellHistory[]>([]); - - useEffect(() => { - (async () => { - let inspect = await inspectCommandHistory(history); - setOther(inspect.other); - })(); - }, []); - - if (other.length == 0) return renderLoading(); - - return ( - <div className="overflow-y-auto"> - <CodeBlock code={history.command} language="bash" /> - - <div> - {other.map((i: any) => { - return <HistoryRow h={i} />; - })} - </div> - </div> - ); -} diff --git a/ui/src/components/history/HistoryRow.tsx b/ui/src/components/history/HistoryRow.tsx deleted file mode 100644 index 4d893e61..00000000 --- a/ui/src/components/history/HistoryRow.tsx +++ /dev/null @@ -1,120 +0,0 @@ -// @ts-ignore -import { DateTime } from "luxon"; -import { ChevronRightIcon } from "@heroicons/react/20/solid"; -import { Highlight, themes } from "prism-react-renderer"; - -// @ts-ignore -import Prism from "prismjs"; - -// @ts-ignore -import "prismjs/components/prism-bash"; - -import Drawer from "../Drawer"; -import HistoryInspect from "./HistoryInspect"; -import { cn } from "@/lib/utils"; - -function msToTime(ms: number) { - let milliseconds = parseInt(ms.toFixed(1)); - let seconds = parseInt((ms / 1000).toFixed(1)); - let minutes = parseInt((ms / (1000 * 60)).toFixed(1)); - let hours = parseInt((ms / (1000 * 60 * 60)).toFixed(1)); - let days = parseInt((ms / (1000 * 60 * 60 * 24)).toFixed(1)); - - if (milliseconds < 1000) return milliseconds + "ms"; - else if (seconds < 60) return seconds + "s"; - else if (minutes < 60) return minutes + "m"; - else if (hours < 24) return hours + "hr"; - else return days + " Days"; -} - -export default function HistoryRow({ h, compact }: any) { - return ( - <li - key={h.id} - className={cn( - "relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50 sm:px-6", - { "py-5": !compact }, - { "py-1": compact }, - )} - > - <div className="flex min-w-0 gap-x-4"> - {!compact && ( - <div className="flex flex-col justify-center"> - <p className="flex text-xs text-gray-500 justify-center"> - {DateTime.fromMillis(h.timestamp / 1000000).toLocaleString( - DateTime.TIME_WITH_SECONDS, - )} - </p> - <p className="flex text-xs mt-1 text-gray-400 justify-center"> - {DateTime.fromMillis(h.timestamp / 1000000).toLocaleString( - DateTime.DATE_SHORT, - )} - </p> - </div> - )} - <div className="min-w-0 flex-col justify-center truncate"> - <Highlight - theme={themes.github} - code={h.command} - language="bash" - prism={Prism} - > - {({ style, tokens, getLineProps, getTokenProps }) => ( - <pre style={style} className="!bg-inherit text-sm"> - {tokens && - tokens.map((line, i) => { - if (i != 0) return; - return ( - <div key={i} {...getLineProps({ line })}> - {line.map((token, key) => ( - <span key={key} {...getTokenProps({ token })} /> - ))} - </div> - ); - })} - </pre> - )} - </Highlight> - <p className="mt-1 flex text-xs leading-5 text-gray-500"> - <span className="relative truncate ">{h.user}</span> - - <span> on </span> - - <span className="relative truncate ">{h.host}</span> - - <span> in </span> - - <span className="relative truncate ">{h.cwd}</span> - </p> - </div> - </div> - <div className="flex shrink-0 items-center gap-x-4"> - <div className="hidden sm:flex sm:flex-col sm:items-end"> - <p className="text-sm leading-6 text-gray-900">{h.exit}</p> - {h.duration ? ( - <p className="mt-1 text-xs leading-5 text-gray-500"> - <time dateTime={h.duration}> - {msToTime(h.duration / 1000000)} - </time> - </p> - ) : ( - <div /> - )} - </div> - <Drawer - width="60%" - trigger={ - <button type="button"> - <ChevronRightIcon - className="h-5 w-5 flex-none text-gray-400" - aria-hidden="true" - /> - </button> - } - > - <HistoryInspect history={h} /> - </Drawer> - </div> - </li> - ); -} diff --git a/ui/src/components/history/Stats.tsx b/ui/src/components/history/Stats.tsx deleted file mode 100644 index f399eaf0..00000000 --- a/ui/src/components/history/Stats.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import { useState, useEffect } from "react"; -import { invoke } from "@tauri-apps/api/core"; -import PacmanLoader from "react-spinners/PacmanLoader"; - -import { - BarChart, - Bar, - XAxis, - YAxis, - Tooltip, - ResponsiveContainer, -} from "recharts"; - -function renderLoading() { - return ( - <div className="flex flex-col items-center justify-center h-full "> - <div> - <PacmanLoader color="#26bd65" /> - </div> - <div className="block mt-4"> - <p>Crunching the latest numbers...</p> - </div> - </div> - ); -} - -function TopTable({ stats }: any) { - return ( - <div className="px-4 sm:px-6 lg:px-8"> - <div className="flex items-center"> - <div className="flex-auto"> - <h1 className="text-base font-semibold">Top commands</h1> - </div> - </div> - <div className="mt-4 flow-root"> - <div className="-mx-4 -my-2 overflow-x-auto sm:-mx-6 lg:-mx-8"> - <div className="inline-block min-w-full py-2 align-middle"> - <table className="min-w-full divide-y divide-gray-300"> - <thead> - <tr> - <th - scope="col" - className="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 lg:pl-8" - > - Command - </th> - <th - scope="col" - className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900" - > - Count - </th> - </tr> - </thead> - <tbody className="divide-y divide-gray-200 bg-white"> - {stats.map((stat: any) => ( - <tr> - <td className="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 lg:pl-8"> - {stat[0][0]} - </td> - <td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500"> - {stat[1]} - </td> - </tr> - ))} - </tbody> - </table> - </div> - </div> - </div> - </div> - ); -} - -export default function Stats() { - const [stats, setStats]: any = useState([]); - const [top, setTop]: any = useState([]); - const [chart, setChart]: any = useState([]); - - useEffect(() => { - if (stats.length != 0) return; - - invoke("global_stats") - .then((s: any) => { - console.log(s.daily); - - setStats([ - { - name: "Total history", - stat: s.total_history.toLocaleString(), - }, - { - name: "Unique history", - stat: s.stats.unique_commands.toLocaleString(), - }, - { - name: "Last 1d", - stat: s.last_1d.toLocaleString(), - }, - { - name: "Last 7d", - stat: s.last_7d.toLocaleString(), - }, - { - name: "Last 30d", - stat: s.last_30d.toLocaleString(), - }, - ]); - - setChart(s.daily); - - setTop(s.stats); - }) - .catch((e) => { - console.log(e); - }); - }, []); - - if (stats.length == 0) { - return renderLoading(); - } - - return ( - <div className="flex flex-col overflow-y-scroll"> - <div className="flexfull"> - <dl className="grid grid-cols-1 sm:grid-cols-5 w-full"> - {stats.map((item: any) => ( - <div - key={item.name} - className="overflow-hidden bg-white px-4 py-5 shadow sm:p-6" - > - <dt className="truncate text-sm font-medium text-gray-500"> - {item.name} - </dt> - <dd className="mt-1 text-3xl font-semibold tracking-tight text-gray-900"> - {item.stat} - </dd> - </div> - ))} - </dl> - </div> - - <div className="flex flex-col h-54 py-4 pl-5"> - <div className="flex flex-col h-48 pt-5 pr-5"> - <ResponsiveContainer width="100%" height="100%"> - <BarChart width={500} height={300} data={chart}> - <XAxis dataKey="name" hide={true} /> - <YAxis /> - <Tooltip /> - <Bar dataKey="value" fill="#26bd65" /> - </BarChart> - </ResponsiveContainer> - </div> - </div> - - <div> - <TopTable stats={top.top} /> - </div> - </div> - ); -} |
