diff --git a/src/hooks/useEditMode.ts b/src/hooks/useEditMode.ts index 11d5d15..c774e53 100644 --- a/src/hooks/useEditMode.ts +++ b/src/hooks/useEditMode.ts @@ -4,7 +4,7 @@ export function useEditMode() { const isEditing = useStore((s) => s.isEditing); const setEditMode = useStore((s) => s.setEditMode); const startEditMode = () => setEditMode(true); - const endEditMode = () => setEditMode(false); + const stopEditMode = () => setEditMode(false); - return { isEditing, setEditMode, startEditMode, endEditMode }; + return { isEditing, setEditMode, startEditMode, stopEditMode }; } diff --git a/src/hooks/useRetoolAppUrl.ts b/src/hooks/useRetoolAppUrl.ts index cdd7ad7..a4f203e 100644 --- a/src/hooks/useRetoolAppUrl.ts +++ b/src/hooks/useRetoolAppUrl.ts @@ -17,6 +17,9 @@ function composeAppUrl(domain: string, app: RetoolApp) { app.query.forEach((q) => url.searchParams.append(q.param, q.value)); + url.searchParams.append("_version", app.version); + url.searchParams.append("_environment", app.env); + if (app.hash.length === 0) { return `${url.toString()}`; } diff --git a/src/pages/Options/Tabs/ConfigTab.tsx b/src/pages/Options/Tabs/ConfigTab.tsx index aadc413..143383d 100644 --- a/src/pages/Options/Tabs/ConfigTab.tsx +++ b/src/pages/Options/Tabs/ConfigTab.tsx @@ -1,9 +1,10 @@ -import React from "react"; -import { Col, Container, Row } from "react-bootstrap"; +import React, { useMemo, useState } from "react"; +import { Button, Col, Container, Row } from "react-bootstrap"; import { FormProvider, useForm } from "react-hook-form"; import { useEditMode } from "@/hooks/useEditMode"; import { useStore } from "@/hooks/useStore"; +import { successToast } from "@/lib/toast"; import AppCard from "../components/AppCard"; import AppForm from "../components/AppForm"; @@ -11,11 +12,25 @@ import DomainInput from "../components/DomainInput"; import type { RetoolApp } from "@/types/extension"; +const NEW_APP: RetoolApp = { + name: "", + public: false, + version: "latest", + env: "development", + hash: [], + query: [], +}; + function ConfigTab() { const methods = useForm(); const { isEditing, startEditMode } = useEditMode(); - const app = useStore((s) => s.getActiveApp()); + const updateActiveApp = useStore((s) => s.updateActiveApp); + + const [creatingNew, setCreatingNew] = useState(false); + const createNewApp = () => { + setCreatingNew(true); + }; return ( <> @@ -25,7 +40,17 @@ function ConfigTab() {

Current App

- {!isEditing ? ( + {isEditing ? ( + + { + updateActiveApp(data); + successToast("Edits saved."); + }} + /> + + ) : ( startEditMode()} /> - ) : ( - - - )} + {!isEditing && !creatingNew && ( +
+ +
+ )} ); } diff --git a/src/pages/Options/components/AppCard.tsx b/src/pages/Options/components/AppCard.tsx index 0591f5d..f03e59b 100644 --- a/src/pages/Options/components/AppCard.tsx +++ b/src/pages/Options/components/AppCard.tsx @@ -29,12 +29,23 @@ type EditProps = BaseProps & { type Props = EditProps | StdProps; function AppCard({ app, isActive, ...props }: Props) { - const { endEditMode } = useEditMode(); const domain = useStore((s) => s.domain); const setActiveApp = useStore((s) => s.setActiveApp); + const { stopEditMode } = useEditMode(); const appUrl = useRetoolAppUrl(domain, app); + const onPreview = () => window.open(appUrl, "_blank"); + + const onActivate = () => { + if (props.editable) { + props.onEdit(); + } else { + stopEditMode(); + setActiveApp(app?.name); + } + }; + return ( - {app?.query && ( - -
Query Params
+ +
Query Params
+ {app?.query && app.query.length ? ( - - )} - {app?.hash && ( - -
Hash Params
+ ) : ( + none + )} + + + +
Hash Params
+ {app?.hash && app.hash.length ? ( - - )} + ) : ( + none + )} +
-
- - Open in Retool - -
-
+
{app?.version[0] === "l" ? app?.version : `v${app?.version}`}
- - + + > + {props.editable ? "Edit" : isActive ? "⭐️ Active" : "Activate"} + +
diff --git a/src/pages/Options/components/AppForm.tsx b/src/pages/Options/components/AppForm.tsx index 547e8eb..6675a42 100644 --- a/src/pages/Options/components/AppForm.tsx +++ b/src/pages/Options/components/AppForm.tsx @@ -18,13 +18,14 @@ import type { RetoolApp } from "@/types/extension"; type Props = { app: RetoolApp; + onSave?: SubmitHandler; }; const INIT_PARAM = { param: "", value: "" }; -function AppForm({ app }: Props) { +function AppForm({ app, onSave }: Props) { const { domain } = useDomain(); - const { setEditMode } = useEditMode(); + const { stopEditMode } = useEditMode(); const updateActiveApp = useStore((s) => s.updateActiveApp); const { @@ -53,8 +54,19 @@ function AppForm({ app }: Props) { errorToast(message); }; + const onCancel = () => { + resetForm(); + stopEditMode(); + }; + + const onDelete = () => { + resetForm(); + stopEditMode(); + alert("BALEETED!"); + }; + return ( -
+
@@ -172,12 +184,7 @@ function AppForm({ app }: Props) { )} /> - { - console.log("Removing Query IDX", index); - queryFields.remove(index); - }} - /> + queryFields.remove(index)} /> ))} queryFields.append(INIT_PARAM)} /> @@ -208,22 +215,17 @@ function AppForm({ app }: Props) { )} /> - { - console.log("Removing Hash IDX", index); - hashFields.remove(index); - }} - /> + hashFields.remove(index)} /> ))} hashFields.append(INIT_PARAM)} /> - + {/* - + */} @@ -231,18 +233,22 @@ function AppForm({ app }: Props) {
+
); diff --git a/src/pages/Options/components/ParameterList.css b/src/pages/Options/components/ParameterList.css new file mode 100644 index 0000000..8f7f83a --- /dev/null +++ b/src/pages/Options/components/ParameterList.css @@ -0,0 +1,43 @@ +.parameter-list { + list-style: none; + margin-left: 0; + padding-left: 0; + + li { + padding-left: 1.5em; + text-indent: -1em; + } + + li::before { + color: grey; + padding-right: 5px; + } + + li:not(:first-child)::before { + content: "&"; + } + + li.query-param:first-child::before { + content: "?"; + } + + li.hash-param:first-child::before { + content: "#"; + } + + .param-name { + margin-right: 5px; + } + + .param-name::after { + content: "="; + color: grey; + padding-left: 5px; + } + + .param-value { + font-weight: bold; + } + + +} \ No newline at end of file diff --git a/src/pages/Options/components/ParameterList.tsx b/src/pages/Options/components/ParameterList.tsx new file mode 100644 index 0000000..4edc59b --- /dev/null +++ b/src/pages/Options/components/ParameterList.tsx @@ -0,0 +1,23 @@ +import "./ParameterList.css"; + +import React from "react"; + +type Props = { + type: "query" | "hash"; + params: [param: string, value: string][]; +}; + +function ParameterList({ params, type }: Props) { + return ( +
    + {params.map(([param, value]) => ( +
  • + {param} + {value} +
  • + ))} +
+ ); +} + +export default ParameterList; diff --git a/src/pages/Options/components/RetoolAppUrl2.tsx b/src/pages/Options/components/RetoolAppUrl2.tsx index 4a4dc2e..9b6395f 100644 --- a/src/pages/Options/components/RetoolAppUrl2.tsx +++ b/src/pages/Options/components/RetoolAppUrl2.tsx @@ -1,27 +1,53 @@ -import JsonView from "@uiw/react-json-view"; -import { githubLightTheme } from "@uiw/react-json-view/githubLight"; -import React, { useMemo } from "react"; -import { Button, Form, InputGroup } from "react-bootstrap"; +import React from "react"; +import { Col, Row } from "react-bootstrap"; import { useRetoolAppUrl } from "@/hooks/useRetoolAppUrl"; +import ParameterList from "./ParameterList"; + import type { RetoolApp } from "@/types/extension"; +type ParameterListParams = React.ComponentProps["params"]; + function RetoolAppUrl2({ app, domain }: { app: RetoolApp; domain: string }) { - const url = useRetoolAppUrl(domain, app); - const jsonUrl = useMemo(() => new URL(url), [url]); + const fullUrl = useRetoolAppUrl(domain, app); + const url = new URL(fullUrl); + + const queryParams = Array.from(url.searchParams.entries()); + + const hashParams: ParameterListParams = app.hash.map((p) => { + return [p.param, p.value]; + }); + + console.log(hashParams); return (
-

Composed URL 2

- +

Composed URL

+ +

{url.origin + url.pathname}

+
+ + +
Query Params:
+
    + +
+ + +
Hash Params:
+
    + {hashParams.length > 0 && ( + + )} +
+ +
); }