Skip to content

Commit

Permalink
fetching remote app list works
Browse files Browse the repository at this point in the history
  • Loading branch information
khill-fbmc committed Oct 14, 2024
1 parent 086cb13 commit 163ace8
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 95 deletions.
6 changes: 3 additions & 3 deletions src/hooks/useExtensionState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type State = {
activeAppName: RetoolApp["name"] | undefined;
// activeApp: RetoolApp | undefined;
workflow: {
url: string;
id: string;
apiKey: string;
};
apps: RetoolApp[];
Expand All @@ -35,8 +35,8 @@ const initialState: State = {
isEditing: false,
activeAppName: INSPECTOR_APP["name"],
workflow: {
url: "",
apiKey: "",
id: "13d34554-9891-40c0-a032-fda523774e97",
apiKey: "retool_wk_bde9d74b27644cf3a0691211ff18dee2",
},
apps: [INSPECTOR_APP, ...DEMO_APPS],
};
Expand Down
8 changes: 4 additions & 4 deletions src/hooks/useRetoolUrl.ts → src/hooks/useRetoolAppUrl.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { RetoolApp } from "@/types/extension";

function useRetoolUrl(domain: string): (app: RetoolApp) => string;
function useRetoolUrl(domain: string, app?: RetoolApp): string;
function useRetoolUrl(domain: string, app?: RetoolApp) {
function useRetoolAppUrl(domain: string): (app: RetoolApp) => string;
function useRetoolAppUrl(domain: string, app?: RetoolApp): string;
function useRetoolAppUrl(domain: string, app?: RetoolApp) {
if (!app) {
return (app: RetoolApp) => composeAppUrl(domain, app);
} else {
Expand All @@ -28,4 +28,4 @@ function composeAppUrl(domain: string, app: RetoolApp) {
return `${url.toString()}#${hashParams.toString()}`;
}

export { useRetoolUrl };
export { useRetoolAppUrl };
3 changes: 3 additions & 0 deletions src/hooks/useRetoolWorkflowUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function useRetoolWorkflowUrl(id: string) {
return `https://api.retool.com/v1/workflows/${id}/startTrigger`;
}
13 changes: 6 additions & 7 deletions src/lib/WorkflowDataFetcher.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import type { RetoolApp } from "@/types/extension";

export async function WorkflowDataFetcher(
export async function getWorkflowApps(
apiKey: string,
url: string
id: string
): Promise<{ apps: RetoolApp[] }> {
return fetch(url, {
const url = `https://api.retool.com/v1/workflows/${id}/startTrigger`;
const res = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Workflow-Api-Key": apiKey,
},
}).then((res) => {
const json = res.json();
console.log(json);
return json;
});

return await res.json();
}
15 changes: 4 additions & 11 deletions src/pages/Options/Tabs/JSONTab.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import JsonView from "@uiw/react-json-view";
import { githubLightTheme } from "@uiw/react-json-view/githubLight";
import React from "react";
import { Card, Col, Row } from "react-bootstrap";
import Container from "react-bootstrap/Container";

import { useExtensionState } from "@/hooks/useExtensionState";

import { SimpleJsonView } from "../components/SimpleJsonView";

function JSONTab() {
const state = useExtensionState();

console.log(state);
return (
<Container className="pb-5">
<div className="d-flex flex-column align-items-center">
Expand All @@ -18,14 +18,7 @@ function JSONTab() {
<Card.Subtitle>Stored Apps and Settings</Card.Subtitle>
</Card.Header>
<Card.Body className="px-4">
<JsonView
value={state}
collapsed={3}
displayDataTypes={false}
enableClipboard={false}
style={githubLightTheme}
shortenTextAfterLength={0}
/>
<SimpleJsonView value={state} />
</Card.Body>
</Card>
</div>
Expand Down
117 changes: 55 additions & 62 deletions src/pages/Options/Tabs/WorkflowTab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import JsonView from "@uiw/react-json-view";
import React, { useEffect, useState } from "react";
import { Alert, Col, Row } from "react-bootstrap";
import Button from "react-bootstrap/Button";
Expand All @@ -8,40 +7,44 @@ import Form from "react-bootstrap/Form";
import useSWR from "swr";

import { useExtensionState } from "@/hooks/useExtensionState";
import { WorkflowDataFetcher } from "@/lib/WorkflowDataFetcher";
import { getWorkflowApps } from "@/lib/WorkflowDataFetcher";

import { SimpleJsonView } from "../components/SimpleJsonView";

import type { RetoolApp } from "@/types/extension";

function WorkflowTab() {
const { apiKey, url } = useExtensionState((s) => s.workflow);
const workflow = useExtensionState((s) => s.workflow);
const updateWorkflow = useExtensionState((s) => s.updateWorkflow);

const [useWorkflowProvider, setUseWorkflowProvider] = useState(false);
const [useProvider, setUseProvider] = useState(false);

const [isLoading, setIsLoading] = useState(false);
const [workflowData, setWorkflowData] = useState<RetoolApp[]>([]);
const [workflowError, setWorkflowError] = useState<string | undefined>();

useEffect(() => {
const fetch = async () => {
setIsLoading(true);
try {
const reply = await WorkflowDataFetcher(apiKey, url);
if (reply.apps) {
setWorkflowData(reply.apps);
}
console.log(reply);
} catch (e) {
setWorkflowError((e as Error).message);
const fetchRemoteApps = async () => {
setIsLoading(true);
try {
const reply = await getWorkflowApps(workflow.apiKey, workflow.id);
if (reply.apps) {
setWorkflowData(reply.apps);
}
setIsLoading(false);
};
if (url && apiKey) fetch();
}, [apiKey, url]);
} catch (e) {
setWorkflowError((e as Error).message);
}
setIsLoading(false);
};

useEffect(() => {
if (useProvider && workflow.id && workflow.apiKey) fetchRemoteApps();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [useProvider, workflow]);

return (
<Container>
<div className="my-2 d-flex">
<h2 className="mx-auto">Workflow Apps List</h2>
<h2 className="mx-auto">Remote Apps List</h2>
</div>

<Row>
Expand Down Expand Up @@ -69,11 +72,11 @@ function WorkflowTab() {
input field, into a dynamic list fetched from a Retool
Workflow.
</p>
<Form.Label>Workflow URL</Form.Label>
<Form.Label>Workflow ID</Form.Label>
<Form.Control
value={url}
disabled={!useWorkflowProvider}
onChange={(e) => updateWorkflow({ url: e.target.value })}
value={workflow.id}
disabled={!useProvider}
onChange={(e) => updateWorkflow({ id: e.target.value })}
/>
<Form.Text className="text-muted">
Supply a Retool workflow URL that returns a <code>200</code>{" "}
Expand All @@ -84,48 +87,32 @@ function WorkflowTab() {
<Form.Label>Workflow API Key</Form.Label>
<Form.Control
type="password"
value={apiKey}
disabled={!useWorkflowProvider}
value={workflow.apiKey}
disabled={!useProvider}
onChange={(e) => updateWorkflow({ apiKey: e.target.value })}
/>
<Form.Text className="text-muted">
Copy this value from Retool
</Form.Text>
</Form.Group>

<Container className="d-flex justify-content-end">
</Card.Body>
<Card.Footer>
<div className="d-flex justify-content-between">
<Button
variant={useWorkflowProvider ? "warning" : "primary"}
variant={useProvider ? "warning" : "primary"}
title={`Enable using a workflow to provide the app name list`}
onClick={() => setUseWorkflowProvider((old) => !old)}
onClick={() => setUseProvider((old) => !old)}
>
{useWorkflowProvider ? "Disable Provider" : "Enable Provider"}
{useProvider ? "Disable Provider" : "Enable Provider"}
</Button>
<Button
variant={"success"}
disabled={useProvider === false}
title={`Refresh the app list from the remote workflow`}
onClick={() => fetchRemoteApps()}
>
Refresh Apps
</Button>
</Container>
</Card.Body>
<Card.Footer>
<div className="d-flex justify-content-between">
<small className="text-muted">Last updated 3 mins ago</small>
<div>
{!useWorkflowProvider ? (
<small className="text-muted">❌ Disabled</small>
) : isLoading ? (
<small className="text-muted">🚀 Fetching...</small>
) : workflowError ? (
<small className="text-danger">
💣 Error! {workflowError}
</small>
) : workflowData.length > 0 ? (
<small className="text-muted">
<span className="text-success">Success.</span> Loaded{" "}
{workflowData.length} app names.
</small>
) : (
<small className="text-muted">
🔦 No results returned.
</small>
)}
</div>
</div>
</Card.Footer>
</Card>
Expand All @@ -140,17 +127,25 @@ function WorkflowTab() {
</div>
</Card.Header>
<Card.Body>
{workflowData.length === 0 ? (
<JsonView value={workflowData} />
{isLoading ? (
<h1>Loading...</h1>
) : (
<Alert>No Apps Returned From Workflow</Alert>
<>
{workflowData.length > 0 ? (
<SimpleJsonView value={workflowData} />
) : (
<Alert variant="danger">
No Apps Returned From Workflow
</Alert>
)}
</>
)}
</Card.Body>
<Card.Footer>
<div className="d-flex justify-content-between">
<small className="text-muted">Last update: 3 mins ago</small>
<div>
{!useWorkflowProvider ? (
{!useProvider ? (
<small className="text-muted">❌ Disabled</small>
) : isLoading ? (
<small className="text-muted">🚀 Fetching...</small>
Expand All @@ -173,8 +168,6 @@ function WorkflowTab() {
</Card.Footer>
</Card>
</Col>

<Col>3</Col>
</Row>
</Container>
);
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Options/components/AppCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Badge, Button, Card, Col, Row } from "react-bootstrap";
import { useDomain } from "@/hooks/useDomain";
import { useEditMode } from "@/hooks/useEditMode";
import { useExtensionState } from "@/hooks/useExtensionState";
import { useRetoolUrl } from "@/hooks/useRetoolUrl";
import { useRetoolAppUrl } from "@/hooks/useRetoolAppUrl";

import type { RetoolApp, UrlParam } from "@/types/extension";

Expand All @@ -33,7 +33,7 @@ function AppCard({ app, isActive, ...props }: Props) {
const { domain } = useDomain();
const setActiveApp = useExtensionState((s) => s.setActiveApp);

const appUrl = useRetoolUrl(domain, app);
const appUrl = useRetoolAppUrl(domain, app);

return (
<Card
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Options/components/RetoolAppUrl.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from "react";
import { Button, Form, InputGroup } from "react-bootstrap";

import { useRetoolUrl } from "@/hooks/useRetoolUrl";
import { useRetoolAppUrl } from "@/hooks/useRetoolAppUrl";

import type { RetoolApp } from "@/types/extension";

function RetoolAppUrl({ app, domain }: { app: RetoolApp; domain: string }) {
const url = useRetoolUrl(domain, app);
const url = useRetoolAppUrl(domain, app);

return (
<Form.Group className="mb-4" controlId="url">
Expand Down
4 changes: 2 additions & 2 deletions src/pages/Options/components/RetoolAppUrl2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { githubLightTheme } from "@uiw/react-json-view/githubLight";
import React, { useMemo } from "react";
import { Button, Form, InputGroup } from "react-bootstrap";

import { useRetoolUrl } from "@/hooks/useRetoolUrl";
import { useRetoolAppUrl } from "@/hooks/useRetoolAppUrl";

import type { RetoolApp } from "@/types/extension";

function RetoolAppUrl2({ app, domain }: { app: RetoolApp; domain: string }) {
const url = useRetoolUrl(domain, app);
const url = useRetoolAppUrl(domain, app);
const jsonUrl = useMemo(() => new URL(url), [url]);

return (
Expand Down
20 changes: 20 additions & 0 deletions src/pages/Options/components/SimpleJsonView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import JsonView from "@uiw/react-json-view";
import { githubLightTheme } from "@uiw/react-json-view/githubLight";
import React from "react";

type Props = {
value: object | undefined;
};

export function SimpleJsonView({ value }: Props) {
return (
<JsonView
value={value}
collapsed={3}
displayDataTypes={false}
enableClipboard={false}
style={githubLightTheme}
shortenTextAfterLength={0}
/>
);
}
4 changes: 2 additions & 2 deletions src/pages/Panel/components/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import React from "react";

import { useActiveApp } from "@/hooks/useActiveApp";
import { useDomain } from "@/hooks/useDomain";
import { useRetoolUrl } from "@/hooks/useRetoolUrl";
import { useRetoolAppUrl } from "@/hooks/useRetoolAppUrl";

import UnsetSettingError from "./UnsetSettingError";

function Panel() {
const { domain } = useDomain();
const app = useActiveApp();
const appUrl = useRetoolUrl(domain);
const appUrl = useRetoolAppUrl(domain);

if (!domain || domain === "") {
return <UnsetSettingError unsetSetting="Instance Name" />;
Expand Down

0 comments on commit 163ace8

Please sign in to comment.