From 5204871dbae45316067d58aacb462b6828fa29b3 Mon Sep 17 00:00:00 2001 From: Igor Bedesqui Date: Mon, 6 Mar 2023 20:23:57 +0000 Subject: [PATCH 01/75] add breadcrumbs and open file button to filerunner --- .../cli/cli-web/src/components/filerunner.tsx | 131 ++++++++++++++++-- 1 file changed, 121 insertions(+), 10 deletions(-) diff --git a/apps/cli/cli-web/src/components/filerunner.tsx b/apps/cli/cli-web/src/components/filerunner.tsx index e76c1f4a..6d4104b4 100644 --- a/apps/cli/cli-web/src/components/filerunner.tsx +++ b/apps/cli/cli-web/src/components/filerunner.tsx @@ -1,16 +1,35 @@ import { CliApiRouter } from "@captain/cli-core"; -import { PlayIcon, PlusIcon, TrashIcon } from "@heroicons/react/20/solid"; +import { + PlayIcon, + PlusIcon, + TrashIcon, + FolderIcon, + HomeIcon, +} from "@heroicons/react/20/solid"; +import toast from "react-hot-toast"; +import { Link } from "wouter"; import { zodResolver } from "@hookform/resolvers/zod"; import { inferRouterOutputs } from "@trpc/server"; import { useForm, useFieldArray } from "react-hook-form"; import { z } from "zod"; +import { Tooltip } from "./common/tooltip"; + import { cliApi } from "../utils/api"; import { classNames } from "../utils/classnames"; import { generateConfigFromState, generatePrefillFromConfig, } from "../utils/configTransforms"; +import { useFileRoute } from "../utils/useRoute"; + +const pathArrToUrl = (pathArr: string[], nav?: string) => { + const url = nav ? `${pathArr.concat(nav).join("/")}` : `${pathArr.join("/")}`; + + // make sure we always have a leading slash + if (!url.startsWith("/")) return `/${url}`; + return url; +}; const jsonValidator = () => z.string().refine( @@ -51,12 +70,16 @@ type FileDataType = Extract["data"]; export const FileRunner = (input: { path: string; data: FileDataType }) => { const { path: file, data } = input; + const pathArr = file.split("/").slice(1); + console.log(pathArr); const path = decodeURI(file).split("/").slice(0, -1); if (path[0] === "") { path.shift(); } + const location = useFileRoute(); + const ctx = cliApi.useContext(); const { mutate: updateHook } = cliApi.updateHook.useMutation({ @@ -132,9 +155,96 @@ export const FileRunner = (input: { path: string; data: FileDataType }) => { }) ); + const { mutate: openFolder } = cliApi.openFolder.useMutation({ + onError: (err) => { + toast.error(err.message); + }, + }); + return ( <>
+ {/* breadcrumbs */} + +
@@ -147,9 +257,10 @@ export const FileRunner = (input: { path: string; data: FileDataType }) => {

-
+
-
+

From a5f32a6551101371607abfe8ea0ecab43780a2fc Mon Sep 17 00:00:00 2001 From: Igor Bedesqui Date: Mon, 6 Mar 2023 23:20:05 +0000 Subject: [PATCH 03/75] extract Nav/breadcrumbs into a component, we can name this better later --- .../cli-web/src/components/breadcrumbs.tsx | 176 ++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 apps/cli/cli-web/src/components/breadcrumbs.tsx diff --git a/apps/cli/cli-web/src/components/breadcrumbs.tsx b/apps/cli/cli-web/src/components/breadcrumbs.tsx new file mode 100644 index 00000000..d3965255 --- /dev/null +++ b/apps/cli/cli-web/src/components/breadcrumbs.tsx @@ -0,0 +1,176 @@ +import { FolderIcon, HomeIcon } from "@heroicons/react/20/solid"; +import { Link } from "wouter"; +import { Tooltip } from "./common/tooltip"; + +import { classNames } from "../utils/classnames"; + +const pathArrToUrl = (pathArr: string[], nav?: string) => { + const url = nav ? `${pathArr.concat(nav).join("/")}` : `${pathArr.join("/")}`; + + // make sure we always have a leading slash + if (!url.startsWith("/")) return `/${url}`; + return url; +}; + +export const Nav = (input: { path: string; actions?: React.ReactNode }) => { + const { path } = input; + + const pathArr = path.split("/").slice(1); + + return ( + + ); +}; + +const Breadcrumbs = (input: { path: string; pathArr: string[] }) => { + const { path, pathArr } = input; + + return ( +
    +
  1. + 1 ? "hover:text-indigo-600" : "cursor-default" + )} + > +
  2. + {path.length > 1 && + pathArr.map((page, i) => ( +
  3. +
    + + + + 48 + ? "" + : "sm:hidden" + )} + aria-hidden="true" + /> + +

    48 + ? "hidden" + : "hidden sm:inline" + )} + > + {page} +

    + +
    +
  4. + ))} +
+ ); +}; From 2bcacb1fe6bd148beeaae0a711ed5c8ca2ce610c Mon Sep 17 00:00:00 2001 From: Igor Bedesqui Date: Tue, 7 Mar 2023 00:51:23 +0000 Subject: [PATCH 04/75] expose `actions` from breadcrumbs (buttons in the right) --- .../cli-web/src/components/breadcrumbs.tsx | 137 ++++++++---------- 1 file changed, 58 insertions(+), 79 deletions(-) diff --git a/apps/cli/cli-web/src/components/breadcrumbs.tsx b/apps/cli/cli-web/src/components/breadcrumbs.tsx index d3965255..a6167bdf 100644 --- a/apps/cli/cli-web/src/components/breadcrumbs.tsx +++ b/apps/cli/cli-web/src/components/breadcrumbs.tsx @@ -12,8 +12,12 @@ const pathArrToUrl = (pathArr: string[], nav?: string) => { return url; }; -export const Nav = (input: { path: string; actions?: React.ReactNode }) => { - const { path } = input; +export const Nav = (input: { + path: string; + actions?: ActionItems; + arbitraryStuffImTooTiredToMakeNice?: React.ReactNode; +}) => { + const { path, actions, arbitraryStuffImTooTiredToMakeNice } = input; const pathArr = path.split("/").slice(1); @@ -23,83 +27,9 @@ export const Nav = (input: { path: string; actions?: React.ReactNode }) => { aria-label="Breadcrumb" > - {/* actions */} - {/*
- - - - - -
- - {`Open create menu`} - -
- - - -
- - {({ active }) => ( -
- -
- )} -
- - {({ active }) => ( -
- -
- )} -
-
-
-
-
-
*/} - - {input.actions} + {actions && ( + + )} ); }; @@ -174,3 +104,52 @@ const Breadcrumbs = (input: { path: string; pathArr: string[] }) => { ); }; + +type ActionsItemCommon = { + label: string | JSX.Element; +}; + +type ActionsItemButton = ActionsItemCommon & { + onClick?: React.MouseEventHandler; + disabled?: boolean; +}; + +type ActionsItemLink = ActionsItemCommon & { + href?: string; +}; + +type ActionsItem = ActionsItemLink | ActionsItemButton; + +// TODO: some better way to have icons here, ping code had `dropdownItemWithIcon` +export type ActionItems = ActionsItem[]; + +const Actions = (input: { items: ActionItems; stuff: React.ReactNode }) => { + return ( +
+ {input.items.map((item, i) => { + if (item?.href) + return ( + + {item.label} + + ); + if (item?.onClick) + return ( + + ); + })} + {input.stuff} +
+ ); +}; From dd8f73a43a3b3e32b56da4e2473e6ae39d3bebdc Mon Sep 17 00:00:00 2001 From: Igor Bedesqui Date: Tue, 7 Mar 2023 00:52:00 +0000 Subject: [PATCH 05/75] use breadcrumbs component (still need to refactor filebrowser's menu bit) --- .../cli-web/src/components/filebrowser.tsx | 100 +++------------ .../cli/cli-web/src/components/filerunner.tsx | 118 +++--------------- 2 files changed, 30 insertions(+), 188 deletions(-) diff --git a/apps/cli/cli-web/src/components/filebrowser.tsx b/apps/cli/cli-web/src/components/filebrowser.tsx index 7d75c57a..a6b5caf5 100644 --- a/apps/cli/cli-web/src/components/filebrowser.tsx +++ b/apps/cli/cli-web/src/components/filebrowser.tsx @@ -5,7 +5,6 @@ import { ExclamationCircleIcon, FolderIcon, FolderPlusIcon, - HomeIcon, InformationCircleIcon, PlayIcon, PlusIcon, @@ -18,6 +17,7 @@ import { Menu, Transition } from "@headlessui/react"; import { CliApiRouter } from "@captain/cli-core"; import { inferRouterOutputs } from "@trpc/server"; +import { Nav } from "./breadcrumbs"; import { Tooltip } from "./common/tooltip"; import { FolderFormModal } from "./folder-form-modal"; @@ -72,92 +72,21 @@ export const FileBrowser = (input: { path: string; data: FolderDataType }) => { return (
{/* breadcrumbs */} - + } + /> + + + {/* folders section */}

diff --git a/apps/cli/cli-web/src/components/filerunner.tsx b/apps/cli/cli-web/src/components/filerunner.tsx index b3c736ad..622c5f6b 100644 --- a/apps/cli/cli-web/src/components/filerunner.tsx +++ b/apps/cli/cli-web/src/components/filerunner.tsx @@ -1,19 +1,12 @@ import { CliApiRouter } from "@captain/cli-core"; -import { - PlayIcon, - PlusIcon, - TrashIcon, - FolderIcon, - HomeIcon, -} from "@heroicons/react/20/solid"; +import { PlayIcon, PlusIcon, TrashIcon } from "@heroicons/react/20/solid"; import toast from "react-hot-toast"; -import { Link } from "wouter"; import { zodResolver } from "@hookform/resolvers/zod"; import { inferRouterOutputs } from "@trpc/server"; import { useForm, useFieldArray } from "react-hook-form"; import { z } from "zod"; -import { Tooltip } from "./common/tooltip"; +import { Nav } from "./breadcrumbs"; import { cliApi } from "../utils/api"; import { classNames } from "../utils/classnames"; @@ -21,15 +14,6 @@ import { generateConfigFromState, generatePrefillFromConfig, } from "../utils/configTransforms"; -import { useFileRoute } from "../utils/useRoute"; - -const pathArrToUrl = (pathArr: string[], nav?: string) => { - const url = nav ? `${pathArr.concat(nav).join("/")}` : `${pathArr.join("/")}`; - - // make sure we always have a leading slash - if (!url.startsWith("/")) return `/${url}`; - return url; -}; const jsonValidator = () => z.string().refine( @@ -65,21 +49,17 @@ const formValidator = z.object({ }); type DataResponse = inferRouterOutputs["parseUrl"]; -type FileDataType = Extract["data"]; +export type FileDataType = Extract["data"]; export const FileRunner = (input: { path: string; data: FileDataType }) => { const { path: file, data } = input; - const pathArr = file.split("/").slice(1); - console.log(pathArr); const path = decodeURI(file).split("/").slice(0, -1); if (path[0] === "") { path.shift(); } - const location = useFileRoute(); - const ctx = cliApi.useContext(); const { mutate: updateHook } = cliApi.updateHook.useMutation({ @@ -155,7 +135,7 @@ export const FileRunner = (input: { path: string; data: FileDataType }) => { }) ); - const { mutate: openFolder } = cliApi.openFolder.useMutation({ + const { mutate: openFile } = cliApi.openFolder.useMutation({ onError: (err) => { toast.error(err.message); }, @@ -163,87 +143,17 @@ export const FileRunner = (input: { path: string; data: FileDataType }) => { return ( <> -
+
{/* breadcrumbs */} - +