diff options
Diffstat (limited to 'ui/src/components/dotfiles')
| -rw-r--r-- | ui/src/components/dotfiles/Aliases.tsx | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/ui/src/components/dotfiles/Aliases.tsx b/ui/src/components/dotfiles/Aliases.tsx new file mode 100644 index 00000000..4854e6b5 --- /dev/null +++ b/ui/src/components/dotfiles/Aliases.tsx @@ -0,0 +1,191 @@ +import React, { useEffect, useState } from "react"; + +import DataTable from "@/components/ui/data-table"; +import { Button } from "@/components/ui/button"; +import { MoreHorizontal } from "lucide-react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +import { invoke } from "@tauri-apps/api/core"; +import Drawer from "@/components/Drawer"; + +function loadAliases( + setAliases: React.Dispatch<React.SetStateAction<never[]>>, +) { + invoke("aliases").then((aliases: any) => { + setAliases(aliases); + }); +} + +type Alias = { + name: string; + value: string; +}; + +function deleteAlias( + name: string, + setAliases: React.Dispatch<React.SetStateAction<never[]>>, +) { + invoke("delete_alias", { name: name }) + .then(() => { + console.log("Deleted alias"); + loadAliases(setAliases); + }) + .catch(() => { + console.error("Failed to delete alias"); + }); +} + +function AddAlias({ onAdd: onAdd }: { onAdd?: () => void }) { + let [name, setName] = useState(""); + let [value, setValue] = useState(""); + + // simple form to add aliases + return ( + <div className="p-4"> + <h2 className="text-xl font-semibold leading-6 text-gray-900"> + Add alias + </h2> + <p className="mt-2">Add a new alias to your shell</p> + + <form + className="mt-4" + onSubmit={(e) => { + e.preventDefault(); + + invoke("set_alias", { name: name, value: value }) + .then(() => { + console.log("Added alias"); + + if (onAdd) onAdd(); + }) + .catch(() => { + console.error("Failed to add alias"); + }); + }} + > + <input + className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-md focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" + type="text" + value={name} + onChange={(e) => setName(e.target.value)} + placeholder="Alias name" + /> + + <input + className="mt-4 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-md focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" + autoComplete="off" + autoCapitalize="off" + autoCorrect="off" + spellCheck="false" + type="text" + value={value} + onChange={(e) => setValue(e.target.value)} + placeholder="Alias value" + /> + + <input + type="submit" + className="block mt-4 rounded-md bg-green-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600" + value="Add alias" + /> + </form> + </div> + ); +} + +export default function Aliases() { + let [aliases, setAliases] = useState([]); + let [aliasDrawerOpen, setAliasDrawerOpen] = useState(false); + + const columns: ColumnDef<Alias>[] = [ + { + accessorKey: "name", + header: "Name", + }, + { + accessorKey: "value", + header: "Value", + }, + { + id: "actions", + cell: ({ row }: any) => { + const alias = row.original; + + return ( + <DropdownMenu> + <DropdownMenuTrigger asChild> + <Button variant="ghost" className="h-8 w-8 p-0 float-right"> + <span className="sr-only">Open menu</span> + <MoreHorizontal className="h-4 w-4 text-right" /> + </Button> + </DropdownMenuTrigger> + <DropdownMenuContent align="end"> + <DropdownMenuLabel>Actions</DropdownMenuLabel> + <DropdownMenuItem + onClick={() => deleteAlias(alias.name, setAliases)} + > + Delete + </DropdownMenuItem> + </DropdownMenuContent> + </DropdownMenu> + ); + }, + }, + ]; + + useEffect(() => { + loadAliases(setAliases); + }, []); + + return ( + <div className="pt-10"> + <div className="sm:flex sm:items-center"> + <div className="sm:flex-auto"> + <h1 className="text-base font-semibold leading-6 text-gray-900"> + Aliases + </h1> + <p className="mt-2 text-sm text-gray-700"> + Aliases allow you to condense long commands into short, + easy-to-remember commands. + </p> + </div> + <div className="mt-4 sm:ml-16 sm:mt-0 flex-row"> + <Drawer + open={aliasDrawerOpen} + onOpenChange={setAliasDrawerOpen} + width="30%" + trigger={ + <button + type="button" + className="block rounded-md bg-green-600 px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-green-600" + > + Add + </button> + } + > + <AddAlias + onAdd={() => { + loadAliases(setAliases); + setAliasDrawerOpen(false); + }} + /> + </Drawer> + </div> + </div> + <div className="mt-8 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 sm:px-6 lg:px-8"> + <DataTable columns={columns} data={aliases} /> + </div> + </div> + </div> + </div> + ); +} |
