From ec80e1d2e17847c3b4cce8f43b56792dad353269 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 17:55:13 -0600 Subject: [PATCH 001/114] Allow apollo-client as a source for messages --- src/extension/messages.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/extension/messages.ts b/src/extension/messages.ts index c9d0d7753..4a99cea12 100644 --- a/src/extension/messages.ts +++ b/src/extension/messages.ts @@ -19,6 +19,7 @@ export function isDevtoolsMessage( typeof message === "object" && message !== null && "source" in message && - message.source === "apollo-client-devtools" + (message.source === "apollo-client-devtools" || + message.source === "apollo-client") ); } From 9097566ace325e49707c00b35fd8af1ce5e95938 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 18:11:36 -0600 Subject: [PATCH 002/114] Add ability to get and store connectors responses --- src/application/App.tsx | 8 +++++++ src/extension/actor.ts | 9 ++++++-- src/types.ts | 50 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/application/App.tsx b/src/application/App.tsx index 9355b3a22..dc7bbed39 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -41,6 +41,7 @@ import { useActorEvent } from "./hooks/useActorEvent"; import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; +import type { ConnectorsDebuggingData } from "../types"; const APP_QUERY: TypedDocumentNode = gql` query AppQuery { @@ -77,6 +78,9 @@ const stableEmptyClients: Required = []; const noop = () => {}; export const App = () => { + const [connectorsPayloads, setConnectorsPayloads] = useState< + ConnectorsDebuggingData[] + >([]); const [snapshot, send] = useMachine( devtoolsMachine.provide({ actions: { @@ -115,6 +119,10 @@ export const App = () => { send({ type: "disconnect" }); }); + useActorEvent("connectorsDebugging", ({ payload }) => { + setConnectorsPayloads((prev) => [...prev, payload.data]); + }); + const [settingsOpen, setSettingsOpen] = useState(false); const [selectedClientId, setSelectedClientId] = useState( data?.clients[0]?.id diff --git a/src/extension/actor.ts b/src/extension/actor.ts index c7448a3c0..6dcd961cf 100644 --- a/src/extension/actor.ts +++ b/src/extension/actor.ts @@ -2,7 +2,11 @@ import { MessageType, isDevtoolsMessage } from "./messages"; import type { MessageAdapter } from "./messageAdapters"; import { createWindowMessageAdapter } from "./messageAdapters"; import { createId } from "../utils/createId"; -import type { ApolloClientInfo, ExplorerResponse } from "../types"; +import type { + ApolloClientInfo, + ConnectorsDebugging, + ExplorerResponse, +} from "../types"; import type { DocumentNode, FetchPolicy } from "@apollo/client"; import type { JSONObject } from "../application/types/json"; @@ -24,7 +28,8 @@ export type ActorMessage = | { type: "pageNavigated" } | { type: "initializePanel" } | { type: "panelHidden" } - | { type: "panelShown" }; + | { type: "panelShown" } + | { type: "connectorsDebugging"; payload: ConnectorsDebugging }; export type ApolloClientDevtoolsActorMessage = { id: string; diff --git a/src/types.ts b/src/types.ts index f18c0bc4a..25bab0ae9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,5 @@ import type { ApolloQueryResult } from "@apollo/client"; +import type { JSONObject } from "./application/types/json"; export type QueryResult = ApolloQueryResult; @@ -26,3 +27,52 @@ export interface ApolloClientInfo { queryCount: number; mutationCount: number; } + +export interface ConnectorsDebugging { + version: string; + data: ConnectorsDebuggingData; +} + +export interface ConnectorsDebuggingRequest { + url: string; + method: string; + headers: [string, string][]; + body: Body | null; +} + +interface SelectionError { + message: string; + path: string; + count: number; +} + +export interface Body { + kind: string; + content: Content; +} + +export type Content = string | JSONObject | JSONObject[] | null | undefined; + +export interface SelectionMappingResponse { + source: string; + transformed: string; + result: JSONObject | JSONObject[] | null; + errors: SelectionError[]; +} + +export interface ConnectorsDebuggingResponse { + status: number; + headers: [string, string][]; + body: Body & { + selection: SelectionMappingResponse; + }; +} +export interface ConnectorsDebuggingData { + request: ConnectorsDebuggingRequest | null | undefined; + response: ConnectorsDebuggingResponse | null | undefined; +} + +export interface ConnectorsDebuggingResult { + version: string; + data: ConnectorsDebuggingData[]; +} From 4008aeb26c94f3a720d482f049c85cc7d82841e5 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 18:23:08 -0600 Subject: [PATCH 003/114] rename type and set full payload in array --- src/application/App.tsx | 4 ++-- src/extension/actor.ts | 4 ++-- src/types.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/application/App.tsx b/src/application/App.tsx index dc7bbed39..a53aee732 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -79,7 +79,7 @@ const noop = () => {}; export const App = () => { const [connectorsPayloads, setConnectorsPayloads] = useState< - ConnectorsDebuggingData[] + ConnectorsDebuggingPayload[] >([]); const [snapshot, send] = useMachine( devtoolsMachine.provide({ @@ -120,7 +120,7 @@ export const App = () => { }); useActorEvent("connectorsDebugging", ({ payload }) => { - setConnectorsPayloads((prev) => [...prev, payload.data]); + setConnectorsPayloads((prev) => [...prev, payload]); }); const [settingsOpen, setSettingsOpen] = useState(false); diff --git a/src/extension/actor.ts b/src/extension/actor.ts index 6dcd961cf..2d1ee4d47 100644 --- a/src/extension/actor.ts +++ b/src/extension/actor.ts @@ -4,7 +4,7 @@ import { createWindowMessageAdapter } from "./messageAdapters"; import { createId } from "../utils/createId"; import type { ApolloClientInfo, - ConnectorsDebugging, + ConnectorsDebuggingPayload, ExplorerResponse, } from "../types"; import type { DocumentNode, FetchPolicy } from "@apollo/client"; @@ -29,7 +29,7 @@ export type ActorMessage = | { type: "initializePanel" } | { type: "panelHidden" } | { type: "panelShown" } - | { type: "connectorsDebugging"; payload: ConnectorsDebugging }; + | { type: "connectorsDebugging"; payload: ConnectorsDebuggingPayload }; export type ApolloClientDevtoolsActorMessage = { id: string; diff --git a/src/types.ts b/src/types.ts index 25bab0ae9..06b9c7e10 100644 --- a/src/types.ts +++ b/src/types.ts @@ -28,7 +28,7 @@ export interface ApolloClientInfo { mutationCount: number; } -export interface ConnectorsDebugging { +export interface ConnectorsDebuggingPayload { version: string; data: ConnectorsDebuggingData; } From 1c9932837a2a5bba2241fcb0ba9e90b951cc4991 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 18:23:27 -0600 Subject: [PATCH 004/114] Start working on a connectors tab --- src/application/App.tsx | 12 ++++++++++- src/application/components/Connectors.tsx | 21 +++++++++++++++++++ .../components/Layouts/Navigation.tsx | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/application/components/Connectors.tsx diff --git a/src/application/App.tsx b/src/application/App.tsx index a53aee732..30e7e7a51 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -41,7 +41,8 @@ import { useActorEvent } from "./hooks/useActorEvent"; import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; -import type { ConnectorsDebuggingData } from "../types"; +import type { ConnectorsDebuggingPayload } from "../types"; +import { Connectors } from "./components/Connectors"; const APP_QUERY: TypedDocumentNode = gql` query AppQuery { @@ -200,6 +201,7 @@ export const App = () => { Mutations ({client?.mutations.total ?? 0}) Cache + Connectors Explorer
@@ -302,6 +304,14 @@ export const App = () => { /> + + + + + diff --git a/src/application/components/Connectors.tsx b/src/application/components/Connectors.tsx new file mode 100644 index 000000000..c6fd22e93 --- /dev/null +++ b/src/application/components/Connectors.tsx @@ -0,0 +1,21 @@ +import type { ConnectorsDebuggingPayload } from "../../types"; + +interface ConnectorsProps { + payloads: ConnectorsDebuggingPayload[]; +} + +export function Connectors({ payloads }: ConnectorsProps) { + console.log(payloads); + return ( +
+

+ Connectors +

+
+ {payloads.map((payload, idx) => { + return
{JSON.stringify(payload.data, null, 2)}
; + })} +
+
+ ); +} diff --git a/src/application/components/Layouts/Navigation.tsx b/src/application/components/Layouts/Navigation.tsx index 14b94a84a..be5bc4289 100644 --- a/src/application/components/Layouts/Navigation.tsx +++ b/src/application/components/Layouts/Navigation.tsx @@ -4,6 +4,7 @@ export enum Screens { Cache = "cache", Queries = "queries", Mutations = "mutations", + Connectors = "connectors", Explorer = "explorer", } From 066bff218d4c0260cc692003d18fabf03eb74b57 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 18:24:13 -0600 Subject: [PATCH 005/114] Fix type of connectors debugging data --- src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types.ts b/src/types.ts index 06b9c7e10..a53e8f7cc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -30,7 +30,7 @@ export interface ApolloClientInfo { export interface ConnectorsDebuggingPayload { version: string; - data: ConnectorsDebuggingData; + data: ConnectorsDebuggingData[]; } export interface ConnectorsDebuggingRequest { From e151b08d35b27dbd49ab51eff89fda907f275db4 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 18:50:59 -0600 Subject: [PATCH 006/114] Provide more info about the operation used in the payload --- src/application/App.tsx | 6 +++--- src/extension/actor.ts | 7 +++++-- src/types.ts | 9 ++++++++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/application/App.tsx b/src/application/App.tsx index 30e7e7a51..3004ac0b1 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -41,7 +41,7 @@ import { useActorEvent } from "./hooks/useActorEvent"; import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; -import type { ConnectorsDebuggingPayload } from "../types"; +import type { ConnectorsDebuggingResultPayload } from "../types"; import { Connectors } from "./components/Connectors"; const APP_QUERY: TypedDocumentNode = gql` @@ -80,7 +80,7 @@ const noop = () => {}; export const App = () => { const [connectorsPayloads, setConnectorsPayloads] = useState< - ConnectorsDebuggingPayload[] + ConnectorsDebuggingResultPayload[] >([]); const [snapshot, send] = useMachine( devtoolsMachine.provide({ @@ -120,7 +120,7 @@ export const App = () => { send({ type: "disconnect" }); }); - useActorEvent("connectorsDebugging", ({ payload }) => { + useActorEvent("connectorsDebuggingResult", ({ payload }) => { setConnectorsPayloads((prev) => [...prev, payload]); }); diff --git a/src/extension/actor.ts b/src/extension/actor.ts index 2d1ee4d47..218fcb3b9 100644 --- a/src/extension/actor.ts +++ b/src/extension/actor.ts @@ -4,7 +4,7 @@ import { createWindowMessageAdapter } from "./messageAdapters"; import { createId } from "../utils/createId"; import type { ApolloClientInfo, - ConnectorsDebuggingPayload, + ConnectorsDebuggingResultPayload, ExplorerResponse, } from "../types"; import type { DocumentNode, FetchPolicy } from "@apollo/client"; @@ -29,7 +29,10 @@ export type ActorMessage = | { type: "initializePanel" } | { type: "panelHidden" } | { type: "panelShown" } - | { type: "connectorsDebugging"; payload: ConnectorsDebuggingPayload }; + | { + type: "connectorsDebuggingResult"; + payload: ConnectorsDebuggingResultPayload; + }; export type ApolloClientDevtoolsActorMessage = { id: string; diff --git a/src/types.ts b/src/types.ts index a53e8f7cc..3e5db7f79 100644 --- a/src/types.ts +++ b/src/types.ts @@ -28,7 +28,14 @@ export interface ApolloClientInfo { mutationCount: number; } -export interface ConnectorsDebuggingPayload { +export interface ConnectorsDebuggingResultPayload { + operationName: string | null; + variables: Record | null; + query: string; + debuggingResult: ConnectorsDebuggingResult; +} + +export interface ConnectorsDebuggingResult { version: string; data: ConnectorsDebuggingData[]; } From ec25c0f13012d42d83803724283283a40e48f3d2 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 19:13:55 -0600 Subject: [PATCH 007/114] Add sidebar with operation names --- src/application/components/Connectors.tsx | 96 ++++++++++++++++++++--- 1 file changed, 83 insertions(+), 13 deletions(-) diff --git a/src/application/components/Connectors.tsx b/src/application/components/Connectors.tsx index c6fd22e93..a555f0d2a 100644 --- a/src/application/components/Connectors.tsx +++ b/src/application/components/Connectors.tsx @@ -1,21 +1,91 @@ -import type { ConnectorsDebuggingPayload } from "../../types"; +import { useMemo, useState } from "react"; +import type { ConnectorsDebuggingResultPayload } from "../../types"; +import { SidebarLayout } from "./Layouts/SidebarLayout"; +import { List } from "./List"; +import { ListItem } from "./ListItem"; +import { SearchField } from "./SearchField"; +import HighlightMatch from "./HighlightMatch"; interface ConnectorsProps { - payloads: ConnectorsDebuggingPayload[]; + payloads: ConnectorsDebuggingResultPayload[]; } export function Connectors({ payloads }: ConnectorsProps) { - console.log(payloads); + const [searchTerm, setSearchTerm] = useState(""); + const payloadsByOperationName = useMemo(() => { + return payloads.reduce((memo, payload) => { + const operationName = payload.operationName ?? "(anonymous)"; + + if (!memo.has(operationName)) { + memo.set(operationName, []); + } + + memo.get(operationName)!.push(payload); + + return memo; + }, new Map()); + }, [payloads]); + + const [selectedOperationName, setSelectedOperationName] = useState( + () => payloadsByOperationName.keys().next().value as string | undefined + ); + + const filteredOperations = useMemo(() => { + const operationNames = Array.from(payloadsByOperationName.keys()); + + if (!searchTerm) { + return operationNames; + } + + const regex = new RegExp(searchTerm, "i"); + + return operationNames.filter((operationName) => regex.test(operationName)); + }, [searchTerm, payloadsByOperationName]); + return ( -
-

- Connectors -

-
- {payloads.map((payload, idx) => { - return
{JSON.stringify(payload.data, null, 2)}
; - })} -
-
+ + + + + {filteredOperations.map((operationName) => { + return ( + setSelectedOperationName(operationName)} + className="font-code" + > + {searchTerm ? ( + + ) : ( + operationName + )} + + ); + })} + + + +

+ Connectors +

+
+ {selectedOperationName && + payloadsByOperationName + .get(selectedOperationName)! + .map((payload, idx) => { + return
{JSON.stringify(payload, null, 2)}
; + })} +
+
+
); } From 4325cdb3544e78a97964147ee9d92f661df7fde7 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 20:13:04 -0600 Subject: [PATCH 008/114] Simplify to show all payloads --- src/application/components/Connectors.tsx | 59 ++++++----------------- 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/src/application/components/Connectors.tsx b/src/application/components/Connectors.tsx index a555f0d2a..3c819853d 100644 --- a/src/application/components/Connectors.tsx +++ b/src/application/components/Connectors.tsx @@ -1,4 +1,4 @@ -import { useMemo, useState } from "react"; +import { useState } from "react"; import type { ConnectorsDebuggingResultPayload } from "../../types"; import { SidebarLayout } from "./Layouts/SidebarLayout"; import { List } from "./List"; @@ -12,35 +12,11 @@ interface ConnectorsProps { export function Connectors({ payloads }: ConnectorsProps) { const [searchTerm, setSearchTerm] = useState(""); - const payloadsByOperationName = useMemo(() => { - return payloads.reduce((memo, payload) => { - const operationName = payload.operationName ?? "(anonymous)"; + const [selectedPayload, setSelectedPayload] = useState(payloads[0]); - if (!memo.has(operationName)) { - memo.set(operationName, []); - } - - memo.get(operationName)!.push(payload); - - return memo; - }, new Map()); - }, [payloads]); - - const [selectedOperationName, setSelectedOperationName] = useState( - () => payloadsByOperationName.keys().next().value as string | undefined - ); - - const filteredOperations = useMemo(() => { - const operationNames = Array.from(payloadsByOperationName.keys()); - - if (!searchTerm) { - return operationNames; - } - - const regex = new RegExp(searchTerm, "i"); - - return operationNames.filter((operationName) => regex.test(operationName)); - }, [searchTerm, payloadsByOperationName]); + if (!selectedPayload && payloads.length > 0) { + setSelectedPayload(payloads[0]); + } return ( @@ -52,21 +28,21 @@ export function Connectors({ payloads }: ConnectorsProps) { value={searchTerm} /> - {filteredOperations.map((operationName) => { + {payloads.map((payload, idx) => { return ( setSelectedOperationName(operationName)} + key={idx} + selected={selectedPayload === payload} + onClick={() => setSelectedPayload(payload)} className="font-code" > {searchTerm ? ( ) : ( - operationName + payload.operationName ?? "(anonymous)" )} ); @@ -77,14 +53,11 @@ export function Connectors({ payloads }: ConnectorsProps) {

Connectors

-
- {selectedOperationName && - payloadsByOperationName - .get(selectedOperationName)! - .map((payload, idx) => { - return
{JSON.stringify(payload, null, 2)}
; - })} -
+ {selectedPayload && ( +
+
{JSON.stringify(selectedPayload, null, 2)}
+
+ )}
); From 37eb44f152ef724413ad92b2f53b569310371b16 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 22:18:31 -0600 Subject: [PATCH 009/114] Ensure hover card has higher z index --- src/application/components/HoverCard/Content.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/HoverCard/Content.tsx b/src/application/components/HoverCard/Content.tsx index e57454c5d..e0acb4894 100644 --- a/src/application/components/HoverCard/Content.tsx +++ b/src/application/components/HoverCard/Content.tsx @@ -14,7 +14,7 @@ export function Content({ className, children }: ContentProps) { collisionPadding={20} sideOffset={2} className={twMerge( - "bg-primary dark:bg-primary-dark border border-primary dark:border-primary-dark rounded-lg px-4 py-3 shadow-popovers text-sm max-w-md overflow-auto max-h-[var(--radix-popper-available-height)] isolate", + "bg-primary dark:bg-primary-dark border border-primary dark:border-primary-dark rounded-lg px-4 py-3 shadow-popovers text-sm max-w-md overflow-auto max-h-[var(--radix-popper-available-height)] isolate z-50", className )} > From d03876bef6d59255985003a50b3260d33717d3bd Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:00:09 -0600 Subject: [PATCH 010/114] Add table components --- src/application/components/Table.tsx | 36 +++++++++++++++ src/application/components/TableContext.tsx | 19 ++++++++ src/application/components/Tbody.tsx | 7 +++ src/application/components/Td.tsx | 51 +++++++++++++++++++++ src/application/components/Th.tsx | 21 +++++++++ src/application/components/Thead.tsx | 12 +++++ src/application/components/Tr.tsx | 16 +++++++ 7 files changed, 162 insertions(+) create mode 100644 src/application/components/Table.tsx create mode 100644 src/application/components/TableContext.tsx create mode 100644 src/application/components/Tbody.tsx create mode 100644 src/application/components/Td.tsx create mode 100644 src/application/components/Th.tsx create mode 100644 src/application/components/Thead.tsx create mode 100644 src/application/components/Tr.tsx diff --git a/src/application/components/Table.tsx b/src/application/components/Table.tsx new file mode 100644 index 000000000..252ad22f3 --- /dev/null +++ b/src/application/components/Table.tsx @@ -0,0 +1,36 @@ +import { useMemo, type ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; +import { TableProvider } from "./TableContext"; + +type NativeTableProps = ComponentPropsWithoutRef<"table">; + +interface TableProps extends NativeTableProps { + interactive?: boolean; + variant?: "plain" | "striped"; + size?: "default" | "condensed"; +} + +export function Table({ + interactive = false, + variant = "plain", + size = "default", + className, + ...props +}: TableProps) { + const contextValue = useMemo( + () => ({ interactive, size, variant }), + [interactive, size, variant] + ); + + return ( + + + + ); +} diff --git a/src/application/components/TableContext.tsx b/src/application/components/TableContext.tsx new file mode 100644 index 000000000..fc5568e1c --- /dev/null +++ b/src/application/components/TableContext.tsx @@ -0,0 +1,19 @@ +import { createContext, useContext } from "react"; + +export interface TableContextValue { + interactive: boolean; + variant: "plain" | "striped"; + size: "default" | "condensed"; +} + +const TableContext = createContext({ + interactive: false, + variant: "plain", + size: "default", +}); + +export const TableProvider = TableContext.Provider; + +export function useTable() { + return useContext(TableContext); +} diff --git a/src/application/components/Tbody.tsx b/src/application/components/Tbody.tsx new file mode 100644 index 000000000..5b810535d --- /dev/null +++ b/src/application/components/Tbody.tsx @@ -0,0 +1,7 @@ +import type { ComponentPropsWithoutRef } from "react"; + +type TbodyProps = ComponentPropsWithoutRef<"tbody">; + +export function Tbody(props: TbodyProps) { + return ; +} diff --git a/src/application/components/Td.tsx b/src/application/components/Td.tsx new file mode 100644 index 000000000..7c751b87e --- /dev/null +++ b/src/application/components/Td.tsx @@ -0,0 +1,51 @@ +import type { ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; +import { cva } from "class-variance-authority"; +import { useTable } from "./TableContext"; + +interface TdProps extends ComponentPropsWithoutRef<"td"> { + formElement?: boolean; + numeric?: boolean; +} + +const td = cva( + [ + "text-primary", + "dark:text-primary-dark", + "border-b", + "border-b-primary", + "dark:border-b-primary-dark", + "px-6", + "py-2", + ], + { + variants: { + size: { + condensed: ["h-10"], + default: ["h-14"], + }, + variant: { + plain: [], + striped: ["group-odd:bg-secondary", "dark:group-odd:bg-secondary-dark"], + }, + }, + } +); + +export function Td({ className, formElement, numeric, ...props }: TdProps) { + const { interactive, size, variant } = useTable(); + + return ( + + ); +} diff --git a/src/application/components/Tr.tsx b/src/application/components/Tr.tsx new file mode 100644 index 000000000..4fe8ad69c --- /dev/null +++ b/src/application/components/Tr.tsx @@ -0,0 +1,16 @@ +import type { ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; + +type TrProps = ComponentPropsWithoutRef<"tr">; + +export function Tr({ className, ...props }: TrProps) { + return ( + + ); +} From 3daa0ff493fec38318e7a832c6ef57ca6d816e4b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:19:34 -0600 Subject: [PATCH 011/114] Add connectors request information in table --- src/application/components/Connectors.tsx | 87 +++++++++++++++++++++-- 1 file changed, 81 insertions(+), 6 deletions(-) diff --git a/src/application/components/Connectors.tsx b/src/application/components/Connectors.tsx index 3c819853d..03063121f 100644 --- a/src/application/components/Connectors.tsx +++ b/src/application/components/Connectors.tsx @@ -1,10 +1,26 @@ import { useState } from "react"; -import type { ConnectorsDebuggingResultPayload } from "../../types"; +import IconInfo from "@apollo/icons/default/IconInfo.svg"; +import type { + ConnectorsDebuggingData, + ConnectorsDebuggingResultPayload, +} from "../../types"; import { SidebarLayout } from "./Layouts/SidebarLayout"; import { List } from "./List"; import { ListItem } from "./ListItem"; import { SearchField } from "./SearchField"; import HighlightMatch from "./HighlightMatch"; +import { Table } from "./Table"; +import { Thead } from "./Thead"; +import { Tooltip } from "./Tooltip"; +import { Tbody } from "./Tbody"; +import { Tr } from "./Tr"; +import { Th } from "./Th"; +import { Td } from "./Td"; +import { CodeBlock } from "./CodeBlock"; +import { Divider } from "./Divider"; +import { Panel, PanelResizeHandle } from "react-resizable-panels"; +import { JSONTreeViewer } from "./JSONTreeViewer"; +import { isEmpty } from "../utilities/isEmpty"; interface ConnectorsProps { payloads: ConnectorsDebuggingResultPayload[]; @@ -49,16 +65,75 @@ export function Connectors({ payloads }: ConnectorsProps) { })} - +

- Connectors + All requests

{selectedPayload && ( -
-
{JSON.stringify(selectedPayload, null, 2)}
-
+ )}
+ {selectedPayload && ( + <> + + + +

+ Variables +

+ +
+ + )} ); } + +function ConnectorsData({ data }: { data: ConnectorsDebuggingData[] }) { + return ( +
+ ); +} diff --git a/src/application/components/Th.tsx b/src/application/components/Th.tsx new file mode 100644 index 000000000..7089132db --- /dev/null +++ b/src/application/components/Th.tsx @@ -0,0 +1,21 @@ +import type { ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; + +interface ThProps extends ComponentPropsWithoutRef<"th"> { + formElement?: boolean; + numeric?: boolean; +} + +export function Th({ className, formElement, numeric, ...props }: ThProps) { + return ( + svg]:shrink-0 group text-start", + formElement && "text-center", + numeric && "text-end", + className + )} + /> + ); +} diff --git a/src/application/components/Thead.tsx b/src/application/components/Thead.tsx new file mode 100644 index 000000000..41533966b --- /dev/null +++ b/src/application/components/Thead.tsx @@ -0,0 +1,12 @@ +import type { ComponentPropsWithoutRef, ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +interface TheadProps extends ComponentPropsWithoutRef<"thead"> { + children: ReactNode; +} + +export function Thead({ className, ...props }: TheadProps) { + return ( +
+ + + + + + + + + + + {data.map(({ request, response }, idx) => { + const url = new URL(request?.url ?? ""); + + return ( + + + + + + + + ); + })} + +
IDPathStatusMethod +
+ Errors{" "} + + + + + +
+
{idx + 1}{url.pathname + url.search}{response?.status}{request?.method}{response?.body?.selection?.errors?.length ?? 0}
+ ); +} From e3989e41a8cf8c1e03fd0b526788c2e2da258d43 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:35:28 -0600 Subject: [PATCH 012/114] Add container query to codeblock to hide text when its narrow --- src/application/components/CodeBlock.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/application/components/CodeBlock.tsx b/src/application/components/CodeBlock.tsx index 48d84351c..5eb1dff0d 100644 --- a/src/application/components/CodeBlock.tsx +++ b/src/application/components/CodeBlock.tsx @@ -144,7 +144,7 @@ export const CodeBlock = ({
@@ -175,7 +175,9 @@ export const CodeBlock = ({ )} From 2a38e9cc8c4b818f7ba1c173f471fe1b9f5fc545 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:35:42 -0600 Subject: [PATCH 013/114] Export status badge props --- src/application/components/StatusBadge.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/StatusBadge.tsx b/src/application/components/StatusBadge.tsx index 21e40eb09..9423c8417 100644 --- a/src/application/components/StatusBadge.tsx +++ b/src/application/components/StatusBadge.tsx @@ -5,7 +5,7 @@ import { cva } from "class-variance-authority"; import type { OmitNull } from "../types/utils"; import { twMerge } from "tailwind-merge"; -interface StatusBadgeProps extends IconVariants, ContainerVariants { +export interface StatusBadgeProps extends IconVariants, ContainerVariants { icon?: ReactElement<{ className: string }>; className?: string; children?: ReactNode; From 0ffbc57cccc4f193e6ffaa5d00290a2957a8b908 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:35:55 -0600 Subject: [PATCH 014/114] Add an http status badge --- src/application/components/Connectors.tsx | 5 ++- .../components/HTTPStatusBadge.tsx | 31 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 src/application/components/HTTPStatusBadge.tsx diff --git a/src/application/components/Connectors.tsx b/src/application/components/Connectors.tsx index 03063121f..951d3507c 100644 --- a/src/application/components/Connectors.tsx +++ b/src/application/components/Connectors.tsx @@ -21,6 +21,7 @@ import { Divider } from "./Divider"; import { Panel, PanelResizeHandle } from "react-resizable-panels"; import { JSONTreeViewer } from "./JSONTreeViewer"; import { isEmpty } from "../utilities/isEmpty"; +import { HTTPStatusBadge } from "./HTTPStatusBadge"; interface ConnectorsProps { payloads: ConnectorsDebuggingResultPayload[]; @@ -127,7 +128,9 @@ function ConnectorsData({ data }: { data: ConnectorsDebuggingData[] }) { {idx + 1} {url.pathname + url.search} - {response?.status} + + + {request?.method} {response?.body?.selection?.errors?.length ?? 0} diff --git a/src/application/components/HTTPStatusBadge.tsx b/src/application/components/HTTPStatusBadge.tsx new file mode 100644 index 000000000..b82df0237 --- /dev/null +++ b/src/application/components/HTTPStatusBadge.tsx @@ -0,0 +1,31 @@ +import { StatusBadge, type StatusBadgeProps } from "./StatusBadge"; + +interface HTTPStatusBadgeProps { + status?: number; +} + +export function HTTPStatusBadge({ status }: HTTPStatusBadgeProps) { + if (status == null) { + return ( + + Unknown + + ); + } + + let color: StatusBadgeProps["color"] = "gray"; + + if (status >= 400) { + color = "red"; + } else if (status >= 300) { + color = "purple"; + } else if (status >= 100) { + color = "green"; + } + + return ( + + {status} + + ); +} From 31a1f37df263567857da764e49117db4ab2ba352 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:38:44 -0600 Subject: [PATCH 015/114] Move to own component --- src/application/components/Connectors.tsx | 62 ++----------------- .../components/ConnectorsRequestList.tsx | 58 +++++++++++++++++ 2 files changed, 63 insertions(+), 57 deletions(-) create mode 100644 src/application/components/ConnectorsRequestList.tsx diff --git a/src/application/components/Connectors.tsx b/src/application/components/Connectors.tsx index 951d3507c..8d9f7ff8c 100644 --- a/src/application/components/Connectors.tsx +++ b/src/application/components/Connectors.tsx @@ -1,27 +1,15 @@ import { useState } from "react"; -import IconInfo from "@apollo/icons/default/IconInfo.svg"; -import type { - ConnectorsDebuggingData, - ConnectorsDebuggingResultPayload, -} from "../../types"; +import type { ConnectorsDebuggingResultPayload } from "../../types"; import { SidebarLayout } from "./Layouts/SidebarLayout"; import { List } from "./List"; import { ListItem } from "./ListItem"; import { SearchField } from "./SearchField"; import HighlightMatch from "./HighlightMatch"; -import { Table } from "./Table"; -import { Thead } from "./Thead"; -import { Tooltip } from "./Tooltip"; -import { Tbody } from "./Tbody"; -import { Tr } from "./Tr"; -import { Th } from "./Th"; -import { Td } from "./Td"; import { CodeBlock } from "./CodeBlock"; -import { Divider } from "./Divider"; import { Panel, PanelResizeHandle } from "react-resizable-panels"; import { JSONTreeViewer } from "./JSONTreeViewer"; import { isEmpty } from "../utilities/isEmpty"; -import { HTTPStatusBadge } from "./HTTPStatusBadge"; +import { ConnectorsRequestList } from "./ConnectorsRequestList"; interface ConnectorsProps { payloads: ConnectorsDebuggingResultPayload[]; @@ -71,7 +59,9 @@ export function Connectors({ payloads }: ConnectorsProps) { All requests {selectedPayload && ( - + )} {selectedPayload && ( @@ -98,45 +88,3 @@ export function Connectors({ payloads }: ConnectorsProps) { ); } - -function ConnectorsData({ data }: { data: ConnectorsDebuggingData[] }) { - return ( - - - - - - - - - - - - {data.map(({ request, response }, idx) => { - const url = new URL(request?.url ?? ""); - - return ( - - - - - - - - ); - })} - -
IDPathStatusMethod -
- Errors{" "} - - - - - -
-
{idx + 1}{url.pathname + url.search} - - {request?.method}{response?.body?.selection?.errors?.length ?? 0}
- ); -} diff --git a/src/application/components/ConnectorsRequestList.tsx b/src/application/components/ConnectorsRequestList.tsx new file mode 100644 index 000000000..00f057307 --- /dev/null +++ b/src/application/components/ConnectorsRequestList.tsx @@ -0,0 +1,58 @@ +import IconInfo from "@apollo/icons/default/IconInfo.svg"; +import { Table } from "./Table"; +import { Th } from "./Th"; +import { Thead } from "./Thead"; +import { Tooltip } from "./Tooltip"; +import { Tr } from "./Tr"; +import { Tbody } from "./Tbody"; +import type { ConnectorsDebuggingData } from "../../types"; +import { Td } from "./Td"; +import { HTTPStatusBadge } from "./HTTPStatusBadge"; + +interface ConnectorsRequestListProps { + requests: ConnectorsDebuggingData[]; +} + +export function ConnectorsRequestList({ + requests, +}: ConnectorsRequestListProps) { + return ( + + + + + + + + + + + + {requests.map(({ request, response }, idx) => { + const url = new URL(request?.url ?? ""); + + return ( + + + + + + + + ); + })} + +
IDPathStatusMethod +
+ Errors{" "} + + + + + +
+
{idx + 1}{url.pathname + url.search} + + {request?.method}{response?.body?.selection?.errors?.length ?? 0}
+ ); +} From 67fb2384aa0851d03e757dd877d4b660c2e14413 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:39:56 -0600 Subject: [PATCH 016/114] Add react router --- package-lock.json | 39 +++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 40 insertions(+) diff --git a/package-lock.json b/package-lock.json index b56886230..0be571548 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,7 @@ "react-json-tree": "^0.19.0", "react-markdown": "^9.0.1", "react-resizable-panels": "^1.0.0", + "react-router-dom": "^6.27.0", "react-syntax-highlighter": "^15.5.0", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", @@ -7213,6 +7214,14 @@ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" } }, + "node_modules/@remix-run/router": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", + "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@repeaterjs/repeater": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@repeaterjs/repeater/-/repeater-3.0.4.tgz", @@ -23226,6 +23235,36 @@ "react-dom": "^16.14.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-router": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", + "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", + "dependencies": { + "@remix-run/router": "1.20.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", + "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", + "dependencies": { + "@remix-run/router": "1.20.0", + "react-router": "6.27.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", diff --git a/package.json b/package.json index 3e956e362..d476c5456 100755 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "react-json-tree": "^0.19.0", "react-markdown": "^9.0.1", "react-resizable-panels": "^1.0.0", + "react-router-dom": "^6.27.0", "react-syntax-highlighter": "^15.5.0", "rehype-raw": "^7.0.0", "remark-gfm": "^4.0.0", From c4f2d979f9c5911998853c7dc1d7186caed3700c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Fri, 18 Oct 2024 23:47:00 -0600 Subject: [PATCH 017/114] Wrap App in router --- src/application/index.tsx | 4 +++- src/application/router.tsx | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/application/router.tsx diff --git a/src/application/index.tsx b/src/application/index.tsx index 5e253075a..3c79f889d 100755 --- a/src/application/index.tsx +++ b/src/application/index.tsx @@ -12,6 +12,8 @@ import * as Tooltip from "@radix-ui/react-tooltip"; import { getRpcClient } from "../extension/devtools/panelRpcClient"; import { createSchemaWithRpcClient } from "./schema"; +import { RouterProvider } from "react-router-dom"; +import { router } from "./router"; loadDevMessages(); loadErrorMessages(); @@ -87,7 +89,7 @@ export const AppProvider = () => { return ( - + ); diff --git a/src/application/router.tsx b/src/application/router.tsx new file mode 100644 index 000000000..0d542cd29 --- /dev/null +++ b/src/application/router.tsx @@ -0,0 +1,11 @@ +import { + createRoutesFromElements, + createMemoryRouter, + Route, +} from "react-router-dom"; + +import { App } from "./App"; + +export const router = createMemoryRouter( + createRoutesFromElements(} />) +); From 8b23175db18f99d545e26f621ed405126c2edb91 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 00:02:20 -0600 Subject: [PATCH 018/114] Use routing to render connectors --- src/application/App.tsx | 15 +++++++++--- src/application/index.tsx | 1 - .../Connectors.tsx => pages/connectors.tsx} | 24 ++++++++++--------- src/application/router.tsx | 7 +++++- 4 files changed, 31 insertions(+), 16 deletions(-) rename src/application/{components/Connectors.tsx => pages/connectors.tsx} (77%) diff --git a/src/application/App.tsx b/src/application/App.tsx index 3004ac0b1..3eaeb5915 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -42,7 +42,7 @@ import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; import type { ConnectorsDebuggingResultPayload } from "../types"; -import { Connectors } from "./components/Connectors"; +import { Outlet, useNavigate } from "react-router-dom"; const APP_QUERY: TypedDocumentNode = gql` query AppQuery { @@ -124,6 +124,7 @@ export const App = () => { setConnectorsPayloads((prev) => [...prev, payload]); }); + const navigate = useNavigate(); const [settingsOpen, setSettingsOpen] = useState(false); const [selectedClientId, setSelectedClientId] = useState( data?.clients[0]?.id @@ -173,7 +174,15 @@ export const App = () => { currentScreen(screen)} + onChange={(screen) => { + currentScreen(screen); + + if (screen === Screens.Connectors) { + navigate("/connectors"); + } else { + navigate("/"); + } + }} className="flex flex-col h-screen bg-primary dark:bg-primary-dark" >
@@ -309,7 +318,7 @@ export const App = () => { value={Screens.Connectors} > - + diff --git a/src/application/index.tsx b/src/application/index.tsx index 3c79f889d..2d221ee27 100755 --- a/src/application/index.tsx +++ b/src/application/index.tsx @@ -6,7 +6,6 @@ import { ApolloClient, ApolloProvider, InMemoryCache } from "@apollo/client"; import { SchemaLink } from "@apollo/client/link/schema"; import { colorTheme, listenForThemeChange } from "./theme"; -import { App } from "./App"; import { fragmentRegistry } from "./fragmentRegistry"; import * as Tooltip from "@radix-ui/react-tooltip"; diff --git a/src/application/components/Connectors.tsx b/src/application/pages/connectors.tsx similarity index 77% rename from src/application/components/Connectors.tsx rename to src/application/pages/connectors.tsx index 8d9f7ff8c..92a8cced1 100644 --- a/src/application/components/Connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -1,21 +1,23 @@ import { useState } from "react"; import type { ConnectorsDebuggingResultPayload } from "../../types"; -import { SidebarLayout } from "./Layouts/SidebarLayout"; -import { List } from "./List"; -import { ListItem } from "./ListItem"; -import { SearchField } from "./SearchField"; -import HighlightMatch from "./HighlightMatch"; -import { CodeBlock } from "./CodeBlock"; +import { SidebarLayout } from "../components/Layouts/SidebarLayout"; +import { List } from "../components/List"; +import { ListItem } from "../components/ListItem"; +import { SearchField } from "../components/SearchField"; +import HighlightMatch from "../components/HighlightMatch"; +import { CodeBlock } from "../components/CodeBlock"; import { Panel, PanelResizeHandle } from "react-resizable-panels"; -import { JSONTreeViewer } from "./JSONTreeViewer"; +import { JSONTreeViewer } from "../components/JSONTreeViewer"; import { isEmpty } from "../utilities/isEmpty"; -import { ConnectorsRequestList } from "./ConnectorsRequestList"; +import { ConnectorsRequestList } from "../components/ConnectorsRequestList"; +import { useOutletContext } from "react-router-dom"; -interface ConnectorsProps { - payloads: ConnectorsDebuggingResultPayload[]; +interface OutletContext { + connectorsPayloads: ConnectorsDebuggingResultPayload[]; } -export function Connectors({ payloads }: ConnectorsProps) { +export function ConnectorsPage() { + const { connectorsPayloads: payloads } = useOutletContext(); const [searchTerm, setSearchTerm] = useState(""); const [selectedPayload, setSelectedPayload] = useState(payloads[0]); diff --git a/src/application/router.tsx b/src/application/router.tsx index 0d542cd29..b540d0ecd 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -5,7 +5,12 @@ import { } from "react-router-dom"; import { App } from "./App"; +import { ConnectorsPage } from "./pages/connectors"; export const router = createMemoryRouter( - createRoutesFromElements(} />) + createRoutesFromElements( + }> + } /> + + ) ); From ae6d938f5bf4c849e04223105d9b041454ef6848 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 00:40:28 -0600 Subject: [PATCH 019/114] WIP router with individual elements --- src/application/App.tsx | 7 +-- src/application/components/ListItem.tsx | 4 +- src/application/pages/connectors.tsx | 51 +++++++++++++--------- src/application/pages/connectors/$id.tsx | 20 +++++++++ src/application/pages/connectors/index.tsx | 13 ++++++ src/application/router.tsx | 7 ++- src/types.ts | 5 +++ 7 files changed, 80 insertions(+), 27 deletions(-) create mode 100644 src/application/pages/connectors/$id.tsx create mode 100644 src/application/pages/connectors/index.tsx diff --git a/src/application/App.tsx b/src/application/App.tsx index 3eaeb5915..98a13ed0a 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -41,7 +41,7 @@ import { useActorEvent } from "./hooks/useActorEvent"; import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; -import type { ConnectorsDebuggingResultPayload } from "../types"; +import type { ConnectorsDebuggingResultPayloadWithId } from "../types"; import { Outlet, useNavigate } from "react-router-dom"; const APP_QUERY: TypedDocumentNode = gql` @@ -77,10 +77,11 @@ ${SECTIONS.devtoolsVersion} const stableEmptyClients: Required = []; const noop = () => {}; +let nextId = 0; export const App = () => { const [connectorsPayloads, setConnectorsPayloads] = useState< - ConnectorsDebuggingResultPayload[] + ConnectorsDebuggingResultPayloadWithId[] >([]); const [snapshot, send] = useMachine( devtoolsMachine.provide({ @@ -121,7 +122,7 @@ export const App = () => { }); useActorEvent("connectorsDebuggingResult", ({ payload }) => { - setConnectorsPayloads((prev) => [...prev, payload]); + setConnectorsPayloads((prev) => [...prev, { ...payload, id: ++nextId }]); }); const navigate = useNavigate(); diff --git a/src/application/components/ListItem.tsx b/src/application/components/ListItem.tsx index 8429b7832..1e1b594ba 100644 --- a/src/application/components/ListItem.tsx +++ b/src/application/components/ListItem.tsx @@ -18,7 +18,6 @@ export function ListItem({
  • { diff --git a/src/application/pages/connectors.tsx b/src/application/pages/connectors.tsx index 92a8cced1..96140a72c 100644 --- a/src/application/pages/connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import type { ConnectorsDebuggingResultPayload } from "../../types"; +import type { ConnectorsDebuggingResultPayloadWithId } from "../../types"; import { SidebarLayout } from "../components/Layouts/SidebarLayout"; import { List } from "../components/List"; import { ListItem } from "../components/ListItem"; @@ -10,21 +10,25 @@ import { Panel, PanelResizeHandle } from "react-resizable-panels"; import { JSONTreeViewer } from "../components/JSONTreeViewer"; import { isEmpty } from "../utilities/isEmpty"; import { ConnectorsRequestList } from "../components/ConnectorsRequestList"; -import { useOutletContext } from "react-router-dom"; +import { + useOutletContext, + matchPath, + useLocation, + Link, + resolvePath, + Outlet, +} from "react-router-dom"; interface OutletContext { - connectorsPayloads: ConnectorsDebuggingResultPayload[]; + connectorsPayloads: ConnectorsDebuggingResultPayloadWithId[]; } export function ConnectorsPage() { const { connectorsPayloads: payloads } = useOutletContext(); + const location = useLocation(); const [searchTerm, setSearchTerm] = useState(""); const [selectedPayload, setSelectedPayload] = useState(payloads[0]); - if (!selectedPayload && payloads.length > 0) { - setSelectedPayload(payloads[0]); - } - return ( @@ -39,27 +43,32 @@ export function ConnectorsPage() { return ( setSelectedPayload(payload)} - className="font-code" + selected={ + resolvePath(`/connectors/${payload.id}`).pathname === + location.pathname + } + className="font-code p-0" > - {searchTerm ? ( - - ) : ( - payload.operationName ?? "(anonymous)" - )} + + {searchTerm ? ( + + ) : ( + payload.operationName ?? "(anonymous)" + )} + ); })} + -

    - All requests -

    {selectedPayload && ( +

    + All requests +

    +
    + ); +} diff --git a/src/application/pages/connectors/index.tsx b/src/application/pages/connectors/index.tsx new file mode 100644 index 000000000..108f1b81f --- /dev/null +++ b/src/application/pages/connectors/index.tsx @@ -0,0 +1,13 @@ +import { EmptyMessage } from "../../components/EmptyMessage"; +import { SidebarLayout } from "../../components/Layouts/SidebarLayout"; + +export function ConnectorsIndexPage() { + return ( + +

    + All requests +

    + +
    + ); +} diff --git a/src/application/router.tsx b/src/application/router.tsx index b540d0ecd..f4d77bd2b 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -6,11 +6,16 @@ import { import { App } from "./App"; import { ConnectorsPage } from "./pages/connectors"; +import { ConnectorsIndexPage } from "./pages/connectors/index"; +import * as ConnectorPage from "./pages/connectors/$id"; export const router = createMemoryRouter( createRoutesFromElements( }> - } /> + }> + } /> + } /> + ) ); diff --git a/src/types.ts b/src/types.ts index 3e5db7f79..439f32d64 100644 --- a/src/types.ts +++ b/src/types.ts @@ -35,6 +35,11 @@ export interface ConnectorsDebuggingResultPayload { debuggingResult: ConnectorsDebuggingResult; } +export interface ConnectorsDebuggingResultPayloadWithId + extends ConnectorsDebuggingResultPayload { + id: number; +} + export interface ConnectorsDebuggingResult { version: string; data: ConnectorsDebuggingData[]; From 3e6c072d40f1d80812c56f37db92c9159193ceb8 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 01:46:49 -0600 Subject: [PATCH 020/114] Render connector request using router --- src/application/App.tsx | 16 +++--- src/application/index.tsx | 10 ++++ src/application/pages/connectors.tsx | 54 ++----------------- src/application/pages/connectors/$id.tsx | 69 +++++++++++++++++++----- src/application/router.tsx | 6 ++- src/application/vars.ts | 6 +++ 6 files changed, 87 insertions(+), 74 deletions(-) create mode 100644 src/application/vars.ts diff --git a/src/application/App.tsx b/src/application/App.tsx index 98a13ed0a..ef6b7bfcc 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { Suspense, useEffect, useState } from "react"; import type { ReactNode } from "react"; import type { TypedDocumentNode } from "@apollo/client"; import { useReactiveVar, gql, useQuery } from "@apollo/client"; @@ -43,6 +43,7 @@ import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; import type { ConnectorsDebuggingResultPayloadWithId } from "../types"; import { Outlet, useNavigate } from "react-router-dom"; +import { PageSpinner } from "./components/PageSpinner"; const APP_QUERY: TypedDocumentNode = gql` query AppQuery { @@ -77,12 +78,9 @@ ${SECTIONS.devtoolsVersion} const stableEmptyClients: Required = []; const noop = () => {}; -let nextId = 0; +const nextId = 0; export const App = () => { - const [connectorsPayloads, setConnectorsPayloads] = useState< - ConnectorsDebuggingResultPayloadWithId[] - >([]); const [snapshot, send] = useMachine( devtoolsMachine.provide({ actions: { @@ -121,10 +119,6 @@ export const App = () => { send({ type: "disconnect" }); }); - useActorEvent("connectorsDebuggingResult", ({ payload }) => { - setConnectorsPayloads((prev) => [...prev, { ...payload, id: ++nextId }]); - }); - const navigate = useNavigate(); const [settingsOpen, setSettingsOpen] = useState(false); const [selectedClientId, setSelectedClientId] = useState( @@ -319,7 +313,9 @@ export const App = () => { value={Screens.Connectors} > - + }> + + diff --git a/src/application/index.tsx b/src/application/index.tsx index 2d221ee27..ecfa289e9 100755 --- a/src/application/index.tsx +++ b/src/application/index.tsx @@ -13,6 +13,8 @@ import { getRpcClient } from "../extension/devtools/panelRpcClient"; import { createSchemaWithRpcClient } from "./schema"; import { RouterProvider } from "react-router-dom"; import { router } from "./router"; +import { getPanelActor } from "../extension/devtools/panelActor"; +import { connectorsRequestsVar } from "./vars"; loadDevMessages(); loadErrorMessages(); @@ -99,3 +101,11 @@ export const initDevTools = () => { root.render(); }; + +let nextPayloadId = 0; +getPanelActor(window).on("connectorsDebuggingResult", ({ payload }) => { + connectorsRequestsVar([ + ...connectorsRequestsVar(), + { ...payload, id: ++nextPayloadId }, + ]); +}); diff --git a/src/application/pages/connectors.tsx b/src/application/pages/connectors.tsx index 96140a72c..0dbe0053b 100644 --- a/src/application/pages/connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -1,33 +1,17 @@ import { useState } from "react"; -import type { ConnectorsDebuggingResultPayloadWithId } from "../../types"; import { SidebarLayout } from "../components/Layouts/SidebarLayout"; import { List } from "../components/List"; import { ListItem } from "../components/ListItem"; import { SearchField } from "../components/SearchField"; import HighlightMatch from "../components/HighlightMatch"; -import { CodeBlock } from "../components/CodeBlock"; -import { Panel, PanelResizeHandle } from "react-resizable-panels"; -import { JSONTreeViewer } from "../components/JSONTreeViewer"; -import { isEmpty } from "../utilities/isEmpty"; -import { ConnectorsRequestList } from "../components/ConnectorsRequestList"; -import { - useOutletContext, - matchPath, - useLocation, - Link, - resolvePath, - Outlet, -} from "react-router-dom"; - -interface OutletContext { - connectorsPayloads: ConnectorsDebuggingResultPayloadWithId[]; -} +import { useLocation, Link, resolvePath, Outlet } from "react-router-dom"; +import { useReactiveVar } from "@apollo/client"; +import { connectorsRequestsVar } from "../vars"; export function ConnectorsPage() { - const { connectorsPayloads: payloads } = useOutletContext(); + const connectorsRequests = useReactiveVar(connectorsRequestsVar); const location = useLocation(); const [searchTerm, setSearchTerm] = useState(""); - const [selectedPayload, setSelectedPayload] = useState(payloads[0]); return ( @@ -39,7 +23,7 @@ export function ConnectorsPage() { value={searchTerm} /> - {payloads.map((payload, idx) => { + {connectorsRequests.map((payload, idx) => { return ( - - {selectedPayload && ( - - )} - - {selectedPayload && ( - <> - - - -

    - Variables -

    - -
    - - )}
    ); } diff --git a/src/application/pages/connectors/$id.tsx b/src/application/pages/connectors/$id.tsx index a32a037d4..40385c8ad 100644 --- a/src/application/pages/connectors/$id.tsx +++ b/src/application/pages/connectors/$id.tsx @@ -1,20 +1,61 @@ -import { - useLoaderData, - useOutletContext, - type LoaderFunctionArgs, -} from "react-router-dom"; -import { SidebarLayout } from "../../components/Layouts/SidebarLayout"; -import type { ConnectorsDebuggingResultPayloadWithId } from "../../../types"; +import { Panel, PanelResizeHandle } from "react-resizable-panels"; +import { Alert } from "../../components/Alert"; import { ConnectorsRequestList } from "../../components/ConnectorsRequestList"; +import { SidebarLayout } from "../../components/Layouts/SidebarLayout"; +import { connectorsRequestsVar } from "../../vars"; +import type { LoaderFunctionArgs } from "react-router-dom"; +import { useLoaderData } from "react-router-dom"; +import { CodeBlock } from "../../components/CodeBlock"; +import { JSONTreeViewer } from "../../components/JSONTreeViewer"; +import { isEmpty } from "../../utilities/isEmpty"; + +export function loader({ params }: LoaderFunctionArgs) { + const request = connectorsRequestsVar().find( + (request) => String(request.id) === params.id + ); + + return { request }; +} + +export function Route() { + const { request } = useLoaderData() as ReturnType; -export function Element() { - const context = useOutletContext(); + if (!request) { + return ( + +

    + All requests +

    + Connectors request not found +
    + ); + } return ( - -

    - All requests -

    -
    + <> + +

    + All requests +

    + +
    + + + +

    + Variables +

    + +
    + ); } diff --git a/src/application/router.tsx b/src/application/router.tsx index f4d77bd2b..e6670c47d 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -14,7 +14,11 @@ export const router = createMemoryRouter( }> }> } /> - } /> + } + loader={ConnectorPage.loader} + /> ) diff --git a/src/application/vars.ts b/src/application/vars.ts new file mode 100644 index 000000000..954b43c06 --- /dev/null +++ b/src/application/vars.ts @@ -0,0 +1,6 @@ +import { makeVar } from "@apollo/client"; +import type { ConnectorsDebuggingResultPayloadWithId } from "../types"; + +export const connectorsRequestsVar = makeVar< + ConnectorsDebuggingResultPayloadWithId[] +>([]); From 8ef9f36132b6ed1c7f1275ce83d998d358a0c781 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 01:50:15 -0600 Subject: [PATCH 021/114] Navigate to first request after blank --- src/application/pages/connectors.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/application/pages/connectors.tsx b/src/application/pages/connectors.tsx index 0dbe0053b..d9b147281 100644 --- a/src/application/pages/connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -4,7 +4,14 @@ import { List } from "../components/List"; import { ListItem } from "../components/ListItem"; import { SearchField } from "../components/SearchField"; import HighlightMatch from "../components/HighlightMatch"; -import { useLocation, Link, resolvePath, Outlet } from "react-router-dom"; +import { + useLocation, + Link, + resolvePath, + Outlet, + Navigate, + useMatch, +} from "react-router-dom"; import { useReactiveVar } from "@apollo/client"; import { connectorsRequestsVar } from "../vars"; @@ -12,6 +19,11 @@ export function ConnectorsPage() { const connectorsRequests = useReactiveVar(connectorsRequestsVar); const location = useLocation(); const [searchTerm, setSearchTerm] = useState(""); + const match = useMatch("/connectors/:id"); + + if (!match && connectorsRequests.length > 0) { + return ; + } return ( From f4a4e17d04dc6c68234cf8fc83eec8739ecc444c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 01:52:19 -0600 Subject: [PATCH 022/114] Add pointer cursor on interactive table rows --- src/application/components/Td.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/Td.tsx b/src/application/components/Td.tsx index 7c751b87e..53e944608 100644 --- a/src/application/components/Td.tsx +++ b/src/application/components/Td.tsx @@ -41,7 +41,7 @@ export function Td({ className, formElement, numeric, ...props }: TdProps) { className={twMerge( td({ size, variant }), interactive && - "group-hover:bg-tableHover dark:group-hover:bg-tableHover-dark empty:before:[content:'–']", + "cursor-pointer group-hover:bg-tableHover dark:group-hover:bg-tableHover-dark empty:before:[content:'–']", formElement && "text-center", numeric && "text-end", className From 4735f25e9cd4d88a29d41ac44bd6d953031efff2 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:00:09 -0600 Subject: [PATCH 023/114] Rename id to operationId in URL --- src/application/pages/connectors.tsx | 2 +- src/application/pages/connectors/$id.tsx | 2 +- src/application/router.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/application/pages/connectors.tsx b/src/application/pages/connectors.tsx index d9b147281..828d88380 100644 --- a/src/application/pages/connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -19,7 +19,7 @@ export function ConnectorsPage() { const connectorsRequests = useReactiveVar(connectorsRequestsVar); const location = useLocation(); const [searchTerm, setSearchTerm] = useState(""); - const match = useMatch("/connectors/:id"); + const match = useMatch("/connectors/:operationId"); if (!match && connectorsRequests.length > 0) { return ; diff --git a/src/application/pages/connectors/$id.tsx b/src/application/pages/connectors/$id.tsx index 40385c8ad..93c082eaa 100644 --- a/src/application/pages/connectors/$id.tsx +++ b/src/application/pages/connectors/$id.tsx @@ -11,7 +11,7 @@ import { isEmpty } from "../../utilities/isEmpty"; export function loader({ params }: LoaderFunctionArgs) { const request = connectorsRequestsVar().find( - (request) => String(request.id) === params.id + (request) => String(request.id) === params.operationId ); return { request }; diff --git a/src/application/router.tsx b/src/application/router.tsx index e6670c47d..a83f4bc76 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -15,7 +15,7 @@ export const router = createMemoryRouter( }> } /> } loader={ConnectorPage.loader} /> From 6ebf97ea93ee1a6e168b113fd8185d43d53fcce8 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:09:22 -0600 Subject: [PATCH 024/114] Add an index route for request page --- src/application/pages/connectors/$id.tsx | 10 +++++++--- src/application/pages/connectors/$id/index.tsx | 8 ++++++++ src/application/router.tsx | 5 ++++- 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 src/application/pages/connectors/$id/index.tsx diff --git a/src/application/pages/connectors/$id.tsx b/src/application/pages/connectors/$id.tsx index 93c082eaa..7f8c637be 100644 --- a/src/application/pages/connectors/$id.tsx +++ b/src/application/pages/connectors/$id.tsx @@ -1,13 +1,13 @@ import { Panel, PanelResizeHandle } from "react-resizable-panels"; import { Alert } from "../../components/Alert"; -import { ConnectorsRequestList } from "../../components/ConnectorsRequestList"; import { SidebarLayout } from "../../components/Layouts/SidebarLayout"; import { connectorsRequestsVar } from "../../vars"; import type { LoaderFunctionArgs } from "react-router-dom"; -import { useLoaderData } from "react-router-dom"; +import { Outlet, useLoaderData, useOutletContext } from "react-router-dom"; import { CodeBlock } from "../../components/CodeBlock"; import { JSONTreeViewer } from "../../components/JSONTreeViewer"; import { isEmpty } from "../../utilities/isEmpty"; +import type { ConnectorsDebuggingResultPayloadWithId } from "../../../types"; export function loader({ params }: LoaderFunctionArgs) { const request = connectorsRequestsVar().find( @@ -37,7 +37,7 @@ export function Route() {

    All requests

    - + ); } + +export function useRequest() { + return useOutletContext(); +} diff --git a/src/application/pages/connectors/$id/index.tsx b/src/application/pages/connectors/$id/index.tsx new file mode 100644 index 000000000..c72086b89 --- /dev/null +++ b/src/application/pages/connectors/$id/index.tsx @@ -0,0 +1,8 @@ +import { ConnectorsRequestList } from "../../../components/ConnectorsRequestList"; +import { useRequest } from "../$id"; + +export function Route() { + const request = useRequest(); + + return ; +} diff --git a/src/application/router.tsx b/src/application/router.tsx index a83f4bc76..8701f6088 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -8,6 +8,7 @@ import { App } from "./App"; import { ConnectorsPage } from "./pages/connectors"; import { ConnectorsIndexPage } from "./pages/connectors/index"; import * as ConnectorPage from "./pages/connectors/$id"; +import * as ConnectorIndexPage from "./pages/connectors/$id/index"; export const router = createMemoryRouter( createRoutesFromElements( @@ -18,7 +19,9 @@ export const router = createMemoryRouter( path=":operationId" element={} loader={ConnectorPage.loader} - /> + > + } /> +
    ) From 4c7f85d0b1f28f1f39f9a734667d621b3b61775c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:10:46 -0600 Subject: [PATCH 025/114] Use similar technique --- src/application/pages/connectors.tsx | 2 +- src/application/pages/connectors/index.tsx | 2 +- src/application/router.tsx | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/application/pages/connectors.tsx b/src/application/pages/connectors.tsx index 828d88380..b14841557 100644 --- a/src/application/pages/connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -15,7 +15,7 @@ import { import { useReactiveVar } from "@apollo/client"; import { connectorsRequestsVar } from "../vars"; -export function ConnectorsPage() { +export function Route() { const connectorsRequests = useReactiveVar(connectorsRequestsVar); const location = useLocation(); const [searchTerm, setSearchTerm] = useState(""); diff --git a/src/application/pages/connectors/index.tsx b/src/application/pages/connectors/index.tsx index 108f1b81f..ea5bb79fa 100644 --- a/src/application/pages/connectors/index.tsx +++ b/src/application/pages/connectors/index.tsx @@ -1,7 +1,7 @@ import { EmptyMessage } from "../../components/EmptyMessage"; import { SidebarLayout } from "../../components/Layouts/SidebarLayout"; -export function ConnectorsIndexPage() { +export function Route() { return (

    diff --git a/src/application/router.tsx b/src/application/router.tsx index 8701f6088..e1a570b80 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -5,16 +5,16 @@ import { } from "react-router-dom"; import { App } from "./App"; -import { ConnectorsPage } from "./pages/connectors"; -import { ConnectorsIndexPage } from "./pages/connectors/index"; +import * as ConnectorsPage from "./pages/connectors"; +import * as ConnectorsIndexPage from "./pages/connectors/index"; import * as ConnectorPage from "./pages/connectors/$id"; import * as ConnectorIndexPage from "./pages/connectors/$id/index"; export const router = createMemoryRouter( createRoutesFromElements( }> - }> - } /> + }> + } /> } From 42ce7b067696eb12102ad2bdb9db53c1e98c0140 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:17:11 -0600 Subject: [PATCH 026/114] Add id to each connectors request --- src/application/components/ConnectorsRequestList.tsx | 10 +++++----- src/application/index.tsx | 12 +++++++++++- src/types.ts | 10 ++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/application/components/ConnectorsRequestList.tsx b/src/application/components/ConnectorsRequestList.tsx index 00f057307..abff821b9 100644 --- a/src/application/components/ConnectorsRequestList.tsx +++ b/src/application/components/ConnectorsRequestList.tsx @@ -5,12 +5,12 @@ import { Thead } from "./Thead"; import { Tooltip } from "./Tooltip"; import { Tr } from "./Tr"; import { Tbody } from "./Tbody"; -import type { ConnectorsDebuggingData } from "../../types"; +import type { ConnectorsDebuggingDataWithId } from "../../types"; import { Td } from "./Td"; import { HTTPStatusBadge } from "./HTTPStatusBadge"; interface ConnectorsRequestListProps { - requests: ConnectorsDebuggingData[]; + requests: ConnectorsDebuggingDataWithId[]; } export function ConnectorsRequestList({ @@ -37,12 +37,12 @@ export function ConnectorsRequestList({ - {requests.map(({ request, response }, idx) => { + {requests.map(({ id, request, response }) => { const url = new URL(request?.url ?? ""); return ( - - {idx + 1} + + {id} {url.pathname + url.search} diff --git a/src/application/index.tsx b/src/application/index.tsx index ecfa289e9..60fdb7f86 100755 --- a/src/application/index.tsx +++ b/src/application/index.tsx @@ -106,6 +106,16 @@ let nextPayloadId = 0; getPanelActor(window).on("connectorsDebuggingResult", ({ payload }) => { connectorsRequestsVar([ ...connectorsRequestsVar(), - { ...payload, id: ++nextPayloadId }, + { + ...payload, + id: ++nextPayloadId, + debuggingResult: { + ...payload.debuggingResult, + data: payload.debuggingResult.data.map((request, idx) => ({ + ...request, + id: idx + 1, + })), + }, + }, ]); }); diff --git a/src/types.ts b/src/types.ts index 439f32d64..57d9c0783 100644 --- a/src/types.ts +++ b/src/types.ts @@ -38,6 +38,7 @@ export interface ConnectorsDebuggingResultPayload { export interface ConnectorsDebuggingResultPayloadWithId extends ConnectorsDebuggingResultPayload { id: number; + debuggingResult: ConnectorsDebuggingResultWithId; } export interface ConnectorsDebuggingResult { @@ -45,6 +46,11 @@ export interface ConnectorsDebuggingResult { data: ConnectorsDebuggingData[]; } +export interface ConnectorsDebuggingResultWithId { + version: string; + data: ConnectorsDebuggingDataWithId[]; +} + export interface ConnectorsDebuggingRequest { url: string; method: string; @@ -84,6 +90,10 @@ export interface ConnectorsDebuggingData { response: ConnectorsDebuggingResponse | null | undefined; } +export interface ConnectorsDebuggingDataWithId extends ConnectorsDebuggingData { + id: number; +} + export interface ConnectorsDebuggingResult { version: string; data: ConnectorsDebuggingData[]; From 86629da9b5eed382fe061bcf98a140187f20f794 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:18:52 -0600 Subject: [PATCH 027/114] Inline the request list into the route component --- .../components/ConnectorsRequestList.tsx | 58 ------------------- .../pages/connectors/$id/index.tsx | 50 +++++++++++++++- 2 files changed, 48 insertions(+), 60 deletions(-) delete mode 100644 src/application/components/ConnectorsRequestList.tsx diff --git a/src/application/components/ConnectorsRequestList.tsx b/src/application/components/ConnectorsRequestList.tsx deleted file mode 100644 index abff821b9..000000000 --- a/src/application/components/ConnectorsRequestList.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import IconInfo from "@apollo/icons/default/IconInfo.svg"; -import { Table } from "./Table"; -import { Th } from "./Th"; -import { Thead } from "./Thead"; -import { Tooltip } from "./Tooltip"; -import { Tr } from "./Tr"; -import { Tbody } from "./Tbody"; -import type { ConnectorsDebuggingDataWithId } from "../../types"; -import { Td } from "./Td"; -import { HTTPStatusBadge } from "./HTTPStatusBadge"; - -interface ConnectorsRequestListProps { - requests: ConnectorsDebuggingDataWithId[]; -} - -export function ConnectorsRequestList({ - requests, -}: ConnectorsRequestListProps) { - return ( - - - - - - - - - - - - {requests.map(({ id, request, response }) => { - const url = new URL(request?.url ?? ""); - - return ( - - - - - - - - ); - })} - -
    IDPathStatusMethod -
    - Errors{" "} - - - - - -
    -
    {id}{url.pathname + url.search} - - {request?.method}{response?.body?.selection?.errors?.length ?? 0}
    - ); -} diff --git a/src/application/pages/connectors/$id/index.tsx b/src/application/pages/connectors/$id/index.tsx index c72086b89..9ece9004d 100644 --- a/src/application/pages/connectors/$id/index.tsx +++ b/src/application/pages/connectors/$id/index.tsx @@ -1,8 +1,54 @@ -import { ConnectorsRequestList } from "../../../components/ConnectorsRequestList"; +import IconInfo from "@apollo/icons/default/IconInfo.svg"; import { useRequest } from "../$id"; +import { Table } from "../../../components/Table"; +import { Thead } from "../../../components/Thead"; +import { Tr } from "../../../components/Tr"; +import { Th } from "../../../components/Th"; +import { Tooltip } from "../../../components/Tooltip"; +import { Td } from "../../../components/Td"; +import { Tbody } from "../../../components/Tbody"; +import { HTTPStatusBadge } from "../../../components/HTTPStatusBadge"; export function Route() { const request = useRequest(); - return ; + return ( + + + + + + + + + + + + {request.debuggingResult.data.map(({ id, request, response }) => { + const url = new URL(request?.url ?? ""); + + return ( + + + + + + + + ); + })} + +
    IDPathStatusMethod +
    + Errors{" "} + + + + + +
    +
    {id}{url.pathname + url.search} + + {request?.method}{response?.body?.selection?.errors?.length ?? 0}
    + ); } From c17e7b4e8ac60ef2851bf691c9f1cf38bacd8d66 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:29:10 -0600 Subject: [PATCH 028/114] Move check for connectors in index route --- src/application/pages/connectors.tsx | 14 +------------- src/application/pages/connectors/index.tsx | 9 +++++++++ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/application/pages/connectors.tsx b/src/application/pages/connectors.tsx index b14841557..6831bdfee 100644 --- a/src/application/pages/connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -4,14 +4,7 @@ import { List } from "../components/List"; import { ListItem } from "../components/ListItem"; import { SearchField } from "../components/SearchField"; import HighlightMatch from "../components/HighlightMatch"; -import { - useLocation, - Link, - resolvePath, - Outlet, - Navigate, - useMatch, -} from "react-router-dom"; +import { useLocation, Link, resolvePath, Outlet } from "react-router-dom"; import { useReactiveVar } from "@apollo/client"; import { connectorsRequestsVar } from "../vars"; @@ -19,11 +12,6 @@ export function Route() { const connectorsRequests = useReactiveVar(connectorsRequestsVar); const location = useLocation(); const [searchTerm, setSearchTerm] = useState(""); - const match = useMatch("/connectors/:operationId"); - - if (!match && connectorsRequests.length > 0) { - return ; - } return ( diff --git a/src/application/pages/connectors/index.tsx b/src/application/pages/connectors/index.tsx index ea5bb79fa..4414836e0 100644 --- a/src/application/pages/connectors/index.tsx +++ b/src/application/pages/connectors/index.tsx @@ -1,7 +1,16 @@ +import { useReactiveVar } from "@apollo/client"; import { EmptyMessage } from "../../components/EmptyMessage"; import { SidebarLayout } from "../../components/Layouts/SidebarLayout"; +import { connectorsRequestsVar } from "../../vars"; +import { Navigate } from "react-router-dom"; export function Route() { + const connectorsRequests = useReactiveVar(connectorsRequestsVar); + + if (connectorsRequests.length > 0) { + return ; + } + return (

    From a4c3ec5608d309dd8c33b538bd5d02503d907609 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:30:27 -0600 Subject: [PATCH 029/114] Renmae folder to match url param --- .../pages/connectors/{$id.tsx => $operationId.tsx} | 0 .../pages/connectors/{$id => $operationId}/index.tsx | 6 ++++-- src/application/router.tsx | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) rename src/application/pages/connectors/{$id.tsx => $operationId.tsx} (100%) rename src/application/pages/connectors/{$id => $operationId}/index.tsx (89%) diff --git a/src/application/pages/connectors/$id.tsx b/src/application/pages/connectors/$operationId.tsx similarity index 100% rename from src/application/pages/connectors/$id.tsx rename to src/application/pages/connectors/$operationId.tsx diff --git a/src/application/pages/connectors/$id/index.tsx b/src/application/pages/connectors/$operationId/index.tsx similarity index 89% rename from src/application/pages/connectors/$id/index.tsx rename to src/application/pages/connectors/$operationId/index.tsx index 9ece9004d..2e9db6fad 100644 --- a/src/application/pages/connectors/$id/index.tsx +++ b/src/application/pages/connectors/$operationId/index.tsx @@ -1,5 +1,5 @@ import IconInfo from "@apollo/icons/default/IconInfo.svg"; -import { useRequest } from "../$id"; +import { useRequest } from "../$operationId"; import { Table } from "../../../components/Table"; import { Thead } from "../../../components/Thead"; import { Tr } from "../../../components/Tr"; @@ -8,9 +8,11 @@ import { Tooltip } from "../../../components/Tooltip"; import { Td } from "../../../components/Td"; import { Tbody } from "../../../components/Tbody"; import { HTTPStatusBadge } from "../../../components/HTTPStatusBadge"; +import { useNavigate } from "react-router-dom"; export function Route() { const request = useRequest(); + const navigate = useNavigate(); return ( @@ -37,7 +39,7 @@ export function Route() { const url = new URL(request?.url ?? ""); return ( - + navigate(String(id))}> navigate(String(id))}> + navigate(`requests/${id}`)}> From ed9a41d9746a844b97d2ee485a55fd671689b5d9 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 10:14:59 -0600 Subject: [PATCH 036/114] Show an icon if there is a selection error --- src/application/components/Tabs/Trigger.tsx | 9 +++++++-- .../connectors/$operationId/requests/$requestId.tsx | 9 ++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/application/components/Tabs/Trigger.tsx b/src/application/components/Tabs/Trigger.tsx index 45c140bae..d61d74367 100644 --- a/src/application/components/Tabs/Trigger.tsx +++ b/src/application/components/Tabs/Trigger.tsx @@ -1,15 +1,20 @@ import type { ReactNode } from "react"; import { Trigger as TriggerBase } from "@radix-ui/react-tabs"; +import { twMerge } from "tailwind-merge"; interface TriggerProps { children: ReactNode; + className?: string; value: string; } -export function Trigger({ children, value }: TriggerProps) { +export function Trigger({ children, className, value }: TriggerProps) { return ( {children} diff --git a/src/application/pages/connectors/$operationId/requests/$requestId.tsx b/src/application/pages/connectors/$operationId/requests/$requestId.tsx index bf1f516e9..fc0ce721f 100644 --- a/src/application/pages/connectors/$operationId/requests/$requestId.tsx +++ b/src/application/pages/connectors/$operationId/requests/$requestId.tsx @@ -3,6 +3,7 @@ import { useRequest } from "../../$operationId"; import { useMemo } from "react"; import { Tabs } from "../../../../components/Tabs"; import { JSONTreeViewer } from "../../../../components/JSONTreeViewer"; +import IconStatusDot from "@apollo/icons/default/IconStatusDot.svg"; export function Route() { const params = useParams(); @@ -17,6 +18,7 @@ export function Route() { ); const response = data.response; + const selectionErrorCount = response?.body.selection?.errors.length ?? 0; return ( @@ -26,7 +28,12 @@ export function Route() { {response?.body && ( Response body )} - Mapping + + Mapping + {selectionErrorCount > 0 && ( + + )} +
    URL: {data.request?.url}
    From f536b179a71680e69ef2706947e90058d94848d7 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 11:25:10 -0600 Subject: [PATCH 037/114] Add card shadow --- tailwind.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tailwind.config.ts b/tailwind.config.ts index d2b35ada1..0578800da 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -38,6 +38,7 @@ export default { }, }, boxShadow: { + cards: "0px 1px 3px 0px rgba(0, 0, 0, 0.06)", dropdown: "0 4px 8px 0 rgba(0, 0, 0, 0.08), 0 0 0 0 rgba(18, 21, 26, 0.04)", modal: From 7be7f87fd2ef6f099845b591ae1d178bd23e9f2c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 11:25:30 -0600 Subject: [PATCH 038/114] Add a card component --- src/application/components/Card.tsx | 213 +++++++++++++++++++++ src/application/components/CardBody.tsx | 43 +++++ src/application/components/CardContext.tsx | 15 ++ 3 files changed, 271 insertions(+) create mode 100644 src/application/components/Card.tsx create mode 100644 src/application/components/CardBody.tsx create mode 100644 src/application/components/CardContext.tsx diff --git a/src/application/components/Card.tsx b/src/application/components/Card.tsx new file mode 100644 index 000000000..e575304c1 --- /dev/null +++ b/src/application/components/Card.tsx @@ -0,0 +1,213 @@ +import { cva } from "class-variance-authority"; +import type { ComponentPropsWithoutRef } from "react"; +import { useMemo } from "react"; +import { CardProvider } from "./CardContext"; +import { twMerge } from "tailwind-merge"; + +interface CardProps extends ComponentPropsWithoutRef<"div"> { + variant?: "filled" | "outline" | "unstyled"; +} + +const card = cva( + [ + "flex", + "flex-col", + "rounded-lg", + "relative", + "min-w-0", + "break-words", + "has-[[data-card-element=body]>table]:overflow-hidden", + ], + { + variants: { + variant: { + filled: [], + outline: [ + "border", + "border-primary", + "dark:border-primary-dark", + "shadow-cards", + ], + unstyled: [], + }, + }, + } +); + +export function Card({ children, className, variant = "outline" }: CardProps) { + const context = useMemo(() => ({ variant }), [variant]); + + return ( + +
    {children}
    +
    + ); +} + +// const baseStyle = definePartsStyle({ +// header: { +// [$groupSpacingY.variable]: 'space.2', +// [$groupSpacingX.variable]: 'space.2', +// display: 'flex', +// flexDirection: 'column', +// gap: 2, +// padding: false, +// pt: $outerPaddingY.reference, +// pb: 4, +// px: $outerPaddingX.reference, +// '&:last-child': { +// pb: $outerPaddingY.reference, +// }, +// '[data-is-divided=true] > &:not(:last-child)': { +// borderBottom: '1px solid', +// borderBottomColor: border.primary, +// }, +// '&:has(> .orbit-group + .orbit-card__header-control)': { +// columnGap: 6, +// }, +// '> .orbit-group[data-direction="horizontal"]:has(> .orbit-group[data-direction="vertical"] + .orbit-card__header-control)': +// { +// [$groupSpacingX.variable]: 'space.6', +// }, +// }, +// headerControl: { +// alignSelf: 'start', +// display: 'flex', +// gap: 3, +// alignItems: 'center', +// '& .chakra-form__label': { +// fontSize: 'sm', +// lineHeight: 'sm', +// fontWeight: 'semibold', +// }, +// }, +// body: { +// [$bodyPaddingX.variable]: 0, +// color: text.primary, +// display: 'flex', +// flexDirection: 'column', +// gap: 4, +// padding: false, +// pt: 4, +// pb: 4, +// px: $outerPaddingX.reference, +// '&:last-child': { +// pb: $outerPaddingY.reference, +// }, +// '&:has(> .chakra-table__container, > .chakra-table)': { +// [$bodyPaddingX.variable]: $outerPaddingX.reference, +// px: 0, +// overflowY: 'auto', +// }, +// '&:has(> .chakra-table__container:first-child, > .chakra-table:first-child)': +// { +// pt: 0, +// }, +// '&:has(> .chakra-table__container:last-child, > .chakra-table:last-child)': +// { +// pb: 0, +// }, +// '&:first-of-type': { +// '&:has(.chakra-table__container)': { +// pt: 0, +// }, +// pt: $outerPaddingY.reference, +// }, +// }, +// title: { +// display: 'flex', +// gap: 2, +// alignItems: 'center', +// }, +// footer: { +// '[data-is-divided=true] > &:not(:first-child)': { +// borderTop: '1px solid', +// borderTopColor: border.primary, +// }, +// '&:has(.orbit-pagination__container)': { +// p: 0, +// }, +// '.chakra-card__body:has(.chakra-table__container:only-child, .chakra-table:only-child) + &:has(.orbit-pagination__container)': +// { +// borderTop: '1px solid', +// borderColor: border.primary, +// }, +// }, +// }); +// +// const tableOverflowContainer = defineStyle({ +// '&:has(.chakra-card__body > .chakra-table__container, .chakra-card__body > .chakra-table)': +// { +// overflow: 'hidden', +// }, +// }); +// +// const tableBorderOverrides = defineStyle({ +// '[data-is-divided=true] &:not(last-child) .chakra-table:last-child tr:last-child td': +// { +// borderBottom: 'none', +// }, +// '&:last-child .chakra-table:last-child tr:last-child td': { +// borderBottom: 'none', +// }, +// '&:has(+ .chakra-card__footer > .orbit-pagination__container) .chakra-table:last-child tr:last-child td': +// { +// borderBottom: 'none', +// }, +// }); +// +// const variantOutline = definePartsStyle({ +// container: { +// [$bg.variable]: bg.primary, +// [$borderColor.variable]: border.primary, +// [$radius.variable]: '0.5rem', +// [$border.variable]: '1px', +// [$outerPaddingY.variable]: 'space.6', +// [$outerPaddingX.variable]: 'space.6', +// color: text.primary, +// boxShadow: 'cards', +// ...tableOverflowContainer, +// }, +// body: { +// ...tableBorderOverrides, +// }, +// }); +// +// const variantFilled = definePartsStyle({ +// container: { +// [$bg.variable]: bg.secondary, +// [$borderColor.variable]: border.primary, +// [$radius.variable]: '0.5rem', +// [$border.variable]: '1px', +// [$outerPaddingY.variable]: 'space.6', +// [$outerPaddingX.variable]: 'space.6', +// color: text.primary, +// ...tableOverflowContainer, +// }, +// body: { +// ...tableBorderOverrides, +// }, +// }); +// +// const variantUnstyled = definePartsStyle({ +// container: { +// [$bg.variable]: false, +// [$outerPaddingY.variable]: 'space.0', +// [$outerPaddingX.variable]: 'space.0', +// backgroundColor: false, +// boxShadow: false, +// }, +// }); +// +// export const CardStyles = defineMultiStyleConfig({ +// baseStyle, +// variants: { +// outline: variantOutline, +// unstyled: variantUnstyled, +// filled: variantFilled, +// }, +// defaultProps: { +// variant: 'outline', +// }, +// }); +// diff --git a/src/application/components/CardBody.tsx b/src/application/components/CardBody.tsx new file mode 100644 index 000000000..430f8428f --- /dev/null +++ b/src/application/components/CardBody.tsx @@ -0,0 +1,43 @@ +import { cva } from "class-variance-authority"; +import { useCard } from "./CardContext"; +import type { ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; + +type CardBodyProps = ComponentPropsWithoutRef<"div">; + +const cardBody = cva( + [ + "flex", + "flex-col", + "gap-4", + "py-4", + "last:pb-6", + "first:py-6", + "has-[>table]:px-0", + "has-[>table]:overflow-y-auto", + "has-[>table:first-child]:pt-0", + "has-[>table:last-child]:pb-0", + "group/card-body", + ], + { + variants: { + variant: { + filled: [], + outline: ["px-6"], + unstyled: [], + }, + }, + } +); + +export function CardBody({ className, ...props }: CardBodyProps) { + const { variant } = useCard(); + + return ( +
    + ); +} diff --git a/src/application/components/CardContext.tsx b/src/application/components/CardContext.tsx new file mode 100644 index 000000000..63f054a7c --- /dev/null +++ b/src/application/components/CardContext.tsx @@ -0,0 +1,15 @@ +import { createContext, useContext } from "react"; + +interface CardContextValue { + variant: "filled" | "outline" | "unstyled"; +} + +const CardContext = createContext({ + variant: "outline", +}); + +export const CardProvider = CardContext.Provider; + +export function useCard() { + return useContext(CardContext); +} From a27d9abb8c305fba7fab8c31c15aa1df2dc68ab5 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 11:25:41 -0600 Subject: [PATCH 039/114] Add additional styles for tables in cards --- src/application/components/Td.tsx | 6 +++++- src/application/components/Tr.tsx | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/application/components/Td.tsx b/src/application/components/Td.tsx index 53e944608..0493270cb 100644 --- a/src/application/components/Td.tsx +++ b/src/application/components/Td.tsx @@ -17,6 +17,7 @@ const td = cva( "dark:border-b-primary-dark", "px-6", "py-2", + "group-[]/card-body:group-last/tr:border-b-0", ], { variants: { @@ -26,7 +27,10 @@ const td = cva( }, variant: { plain: [], - striped: ["group-odd:bg-secondary", "dark:group-odd:bg-secondary-dark"], + striped: [ + "group-odd/tr:bg-secondary", + "dark:group-odd/tr:bg-secondary-dark", + ], }, }, } diff --git a/src/application/components/Tr.tsx b/src/application/components/Tr.tsx index 4fe8ad69c..6c3376c37 100644 --- a/src/application/components/Tr.tsx +++ b/src/application/components/Tr.tsx @@ -8,7 +8,7 @@ export function Tr({ className, ...props }: TrProps) {
    From f0e6fcdee2cf8cb42c1c62ed55de9bc586a85ffd Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 11:28:34 -0600 Subject: [PATCH 040/114] Remove commented styles --- src/application/components/Card.tsx | 168 ---------------------------- 1 file changed, 168 deletions(-) diff --git a/src/application/components/Card.tsx b/src/application/components/Card.tsx index e575304c1..86d27fe7a 100644 --- a/src/application/components/Card.tsx +++ b/src/application/components/Card.tsx @@ -43,171 +43,3 @@ export function Card({ children, className, variant = "outline" }: CardProps) { ); } - -// const baseStyle = definePartsStyle({ -// header: { -// [$groupSpacingY.variable]: 'space.2', -// [$groupSpacingX.variable]: 'space.2', -// display: 'flex', -// flexDirection: 'column', -// gap: 2, -// padding: false, -// pt: $outerPaddingY.reference, -// pb: 4, -// px: $outerPaddingX.reference, -// '&:last-child': { -// pb: $outerPaddingY.reference, -// }, -// '[data-is-divided=true] > &:not(:last-child)': { -// borderBottom: '1px solid', -// borderBottomColor: border.primary, -// }, -// '&:has(> .orbit-group + .orbit-card__header-control)': { -// columnGap: 6, -// }, -// '> .orbit-group[data-direction="horizontal"]:has(> .orbit-group[data-direction="vertical"] + .orbit-card__header-control)': -// { -// [$groupSpacingX.variable]: 'space.6', -// }, -// }, -// headerControl: { -// alignSelf: 'start', -// display: 'flex', -// gap: 3, -// alignItems: 'center', -// '& .chakra-form__label': { -// fontSize: 'sm', -// lineHeight: 'sm', -// fontWeight: 'semibold', -// }, -// }, -// body: { -// [$bodyPaddingX.variable]: 0, -// color: text.primary, -// display: 'flex', -// flexDirection: 'column', -// gap: 4, -// padding: false, -// pt: 4, -// pb: 4, -// px: $outerPaddingX.reference, -// '&:last-child': { -// pb: $outerPaddingY.reference, -// }, -// '&:has(> .chakra-table__container, > .chakra-table)': { -// [$bodyPaddingX.variable]: $outerPaddingX.reference, -// px: 0, -// overflowY: 'auto', -// }, -// '&:has(> .chakra-table__container:first-child, > .chakra-table:first-child)': -// { -// pt: 0, -// }, -// '&:has(> .chakra-table__container:last-child, > .chakra-table:last-child)': -// { -// pb: 0, -// }, -// '&:first-of-type': { -// '&:has(.chakra-table__container)': { -// pt: 0, -// }, -// pt: $outerPaddingY.reference, -// }, -// }, -// title: { -// display: 'flex', -// gap: 2, -// alignItems: 'center', -// }, -// footer: { -// '[data-is-divided=true] > &:not(:first-child)': { -// borderTop: '1px solid', -// borderTopColor: border.primary, -// }, -// '&:has(.orbit-pagination__container)': { -// p: 0, -// }, -// '.chakra-card__body:has(.chakra-table__container:only-child, .chakra-table:only-child) + &:has(.orbit-pagination__container)': -// { -// borderTop: '1px solid', -// borderColor: border.primary, -// }, -// }, -// }); -// -// const tableOverflowContainer = defineStyle({ -// '&:has(.chakra-card__body > .chakra-table__container, .chakra-card__body > .chakra-table)': -// { -// overflow: 'hidden', -// }, -// }); -// -// const tableBorderOverrides = defineStyle({ -// '[data-is-divided=true] &:not(last-child) .chakra-table:last-child tr:last-child td': -// { -// borderBottom: 'none', -// }, -// '&:last-child .chakra-table:last-child tr:last-child td': { -// borderBottom: 'none', -// }, -// '&:has(+ .chakra-card__footer > .orbit-pagination__container) .chakra-table:last-child tr:last-child td': -// { -// borderBottom: 'none', -// }, -// }); -// -// const variantOutline = definePartsStyle({ -// container: { -// [$bg.variable]: bg.primary, -// [$borderColor.variable]: border.primary, -// [$radius.variable]: '0.5rem', -// [$border.variable]: '1px', -// [$outerPaddingY.variable]: 'space.6', -// [$outerPaddingX.variable]: 'space.6', -// color: text.primary, -// boxShadow: 'cards', -// ...tableOverflowContainer, -// }, -// body: { -// ...tableBorderOverrides, -// }, -// }); -// -// const variantFilled = definePartsStyle({ -// container: { -// [$bg.variable]: bg.secondary, -// [$borderColor.variable]: border.primary, -// [$radius.variable]: '0.5rem', -// [$border.variable]: '1px', -// [$outerPaddingY.variable]: 'space.6', -// [$outerPaddingX.variable]: 'space.6', -// color: text.primary, -// ...tableOverflowContainer, -// }, -// body: { -// ...tableBorderOverrides, -// }, -// }); -// -// const variantUnstyled = definePartsStyle({ -// container: { -// [$bg.variable]: false, -// [$outerPaddingY.variable]: 'space.0', -// [$outerPaddingX.variable]: 'space.0', -// backgroundColor: false, -// boxShadow: false, -// }, -// }); -// -// export const CardStyles = defineMultiStyleConfig({ -// baseStyle, -// variants: { -// outline: variantOutline, -// unstyled: variantUnstyled, -// filled: variantFilled, -// }, -// defaultProps: { -// variant: 'outline', -// }, -// }); -// From 3f4b695bb447b9e7cd06a12aba71efe50892cda5 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 11:28:45 -0600 Subject: [PATCH 041/114] Render table in card --- .../pages/connectors/$operationId/index.tsx | 81 ++++++++++--------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/src/application/pages/connectors/$operationId/index.tsx b/src/application/pages/connectors/$operationId/index.tsx index 610fba01d..bd30215c0 100644 --- a/src/application/pages/connectors/$operationId/index.tsx +++ b/src/application/pages/connectors/$operationId/index.tsx @@ -9,48 +9,57 @@ import { Td } from "../../../components/Td"; import { Tbody } from "../../../components/Tbody"; import { HTTPStatusBadge } from "../../../components/HTTPStatusBadge"; import { useNavigate } from "react-router-dom"; +import { Card } from "../../../components/Card"; +import { CardBody } from "../../../components/CardBody"; export function Route() { const request = useRequest(); const navigate = useNavigate(); return ( -
    {id} {url.pathname + url.search} diff --git a/src/application/router.tsx b/src/application/router.tsx index e1a570b80..ea83034fb 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -7,8 +7,8 @@ import { import { App } from "./App"; import * as ConnectorsPage from "./pages/connectors"; import * as ConnectorsIndexPage from "./pages/connectors/index"; -import * as ConnectorPage from "./pages/connectors/$id"; -import * as ConnectorIndexPage from "./pages/connectors/$id/index"; +import * as ConnectorPage from "./pages/connectors/$operationId"; +import * as ConnectorIndexPage from "./pages/connectors/$operationId/index"; export const router = createMemoryRouter( createRoutesFromElements( From bbd69f9f8a7faf9bf78e5d9d6ece0575e1c5fbb5 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:43:10 -0600 Subject: [PATCH 030/114] Add more resiliency to link matching --- src/application/pages/connectors.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/application/pages/connectors.tsx b/src/application/pages/connectors.tsx index 6831bdfee..f821c8c91 100644 --- a/src/application/pages/connectors.tsx +++ b/src/application/pages/connectors.tsx @@ -24,12 +24,16 @@ export function Route() { /> {connectorsRequests.map((payload, idx) => { + const { pathname: toPathname } = resolvePath( + `/connectors/${payload.id}` + ); + return ( From 54a652b7f0524c36bbdbf5dcfe4f391568de2abb Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:44:20 -0600 Subject: [PATCH 031/114] Remove unused import --- src/application/App.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/application/App.tsx b/src/application/App.tsx index ef6b7bfcc..1f31a6652 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -41,7 +41,6 @@ import { useActorEvent } from "./hooks/useActorEvent"; import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; -import type { ConnectorsDebuggingResultPayloadWithId } from "../types"; import { Outlet, useNavigate } from "react-router-dom"; import { PageSpinner } from "./components/PageSpinner"; From d9cfe58fbfe9ffec359abdbb5634f6a06056eafd Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:44:33 -0600 Subject: [PATCH 032/114] Remove unused variable --- src/application/App.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/application/App.tsx b/src/application/App.tsx index 1f31a6652..91911c12e 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -77,7 +77,6 @@ ${SECTIONS.devtoolsVersion} const stableEmptyClients: Required = []; const noop = () => {}; -const nextId = 0; export const App = () => { const [snapshot, send] = useMachine( From 7dd21cc458d8dbd896592f65cf17e5bab4f169a7 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 02:55:17 -0600 Subject: [PATCH 033/114] WIP request detail --- .../pages/connectors/$operationId/index.tsx | 2 +- .../$operationId/requests/$requestId.tsx | 55 +++++++++++++++++++ src/application/router.tsx | 5 ++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/application/pages/connectors/$operationId/requests/$requestId.tsx diff --git a/src/application/pages/connectors/$operationId/index.tsx b/src/application/pages/connectors/$operationId/index.tsx index 2e9db6fad..0604d15ea 100644 --- a/src/application/pages/connectors/$operationId/index.tsx +++ b/src/application/pages/connectors/$operationId/index.tsx @@ -39,7 +39,7 @@ export function Route() { const url = new URL(request?.url ?? ""); return ( -
    {id} {url.pathname + url.search} diff --git a/src/application/pages/connectors/$operationId/requests/$requestId.tsx b/src/application/pages/connectors/$operationId/requests/$requestId.tsx new file mode 100644 index 000000000..bf1f516e9 --- /dev/null +++ b/src/application/pages/connectors/$operationId/requests/$requestId.tsx @@ -0,0 +1,55 @@ +import { useParams } from "react-router-dom"; +import { useRequest } from "../../$operationId"; +import { useMemo } from "react"; +import { Tabs } from "../../../../components/Tabs"; +import { JSONTreeViewer } from "../../../../components/JSONTreeViewer"; + +export function Route() { + const params = useParams(); + const request = useRequest(); + + const data = useMemo( + () => + request.debuggingResult.data.find( + ({ id }) => String(id) === params.requestId + )!, + [request, params.requestId] + ); + + const response = data.response; + + return ( + + + Request overview + Response overview + {response?.body && ( + Response body + )} + Mapping + + +
    URL: {data.request?.url}
    +
    + +
    Status code: {data.response?.status}
    +
    + {response?.body && ( + + {response.body.kind === "json" ? ( + + ) : ( + String(response.body.content) + )} + + )} + +
    Mapping:
    +
    +
    + ); +} diff --git a/src/application/router.tsx b/src/application/router.tsx index ea83034fb..07e1767f9 100644 --- a/src/application/router.tsx +++ b/src/application/router.tsx @@ -9,6 +9,7 @@ import * as ConnectorsPage from "./pages/connectors"; import * as ConnectorsIndexPage from "./pages/connectors/index"; import * as ConnectorPage from "./pages/connectors/$operationId"; import * as ConnectorIndexPage from "./pages/connectors/$operationId/index"; +import * as ConnectorRequestPage from "./pages/connectors/$operationId/requests/$requestId"; export const router = createMemoryRouter( createRoutesFromElements( @@ -21,6 +22,10 @@ export const router = createMemoryRouter( loader={ConnectorPage.loader} > } /> + } + /> From ef86bef6d16962982a4495e816cc1f65f2866f72 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Sat, 19 Oct 2024 03:00:21 -0600 Subject: [PATCH 034/114] Clear requests when refreshing the page --- src/application/index.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/application/index.tsx b/src/application/index.tsx index 60fdb7f86..9b0bc8af5 100755 --- a/src/application/index.tsx +++ b/src/application/index.tsx @@ -103,7 +103,9 @@ export const initDevTools = () => { }; let nextPayloadId = 0; -getPanelActor(window).on("connectorsDebuggingResult", ({ payload }) => { +const actor = getPanelActor(window); + +actor.on("connectorsDebuggingResult", ({ payload }) => { connectorsRequestsVar([ ...connectorsRequestsVar(), { @@ -119,3 +121,6 @@ getPanelActor(window).on("connectorsDebuggingResult", ({ payload }) => { }, ]); }); + +actor.on("pageNavigated", () => connectorsRequestsVar([])); +actor.on("clientTerminated", () => connectorsRequestsVar([])); From 7807012d749925f86ff8dd8be5c40e093149957f Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 10:12:08 -0600 Subject: [PATCH 035/114] Add ability to show status code label --- .../components/HTTPStatusBadge.tsx | 71 ++++++++++++++++++- .../pages/connectors/$operationId/index.tsx | 2 +- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/src/application/components/HTTPStatusBadge.tsx b/src/application/components/HTTPStatusBadge.tsx index b82df0237..97c1e93b0 100644 --- a/src/application/components/HTTPStatusBadge.tsx +++ b/src/application/components/HTTPStatusBadge.tsx @@ -2,9 +2,10 @@ import { StatusBadge, type StatusBadgeProps } from "./StatusBadge"; interface HTTPStatusBadgeProps { status?: number; + variant: "terse" | "full"; } -export function HTTPStatusBadge({ status }: HTTPStatusBadgeProps) { +export function HTTPStatusBadge({ status, variant }: HTTPStatusBadgeProps) { if (status == null) { return ( @@ -26,6 +27,74 @@ export function HTTPStatusBadge({ status }: HTTPStatusBadgeProps) { return ( {status} + {variant === "full" && ` ${STATUS_CODE_LABELS.get(status)}`} ); } + +// https://en.wikipedia.org/wiki/List_of_HTTP_status_codes +export const STATUS_CODE_LABELS = new Map([ + [100, "Continue"], + [101, "Switching protocols"], + [102, "Processing"], + [103, "Early hints"], + [200, "Ok"], + [201, "Created"], + [202, "Accepted"], + [203, "Non-authoritative information"], + [204, "No content"], + [205, "Reset content"], + [206, "Partial content"], + [207, "Multi-status"], + [208, "Already reported"], + [226, "IM used"], + [300, "Multiple choices"], + [301, "Moved permanently"], + [302, 'Found (previously "moved temporarily")'], + [303, "See other"], + [304, "Not modified"], + [305, "Use proxy"], + [306, "Switch proxy"], + [307, "Temporary redirect"], + [308, "Permanent redirect"], + [400, "Bad request"], + [401, "Unauthorized"], + [402, "Payment required"], + [403, "Forbidden"], + [404, "Not found"], + [405, "Method not allowed"], + [406, "Not acceptable"], + [407, "Proxy authentication required"], + [408, "Request timeout"], + [409, "Conflict"], + [410, "Gone"], + [411, "Length required"], + [412, "Precondition failed"], + [413, "Payload too large"], + [414, "URI too long"], + [415, "Unsupported media type"], + [416, "Range not satisfiable"], + [417, "Expectation failed"], + [418, "I'm a teapot"], + [421, "Misdirected request"], + [422, "Unprocessable content"], + [423, "Locked"], + [424, "Failed dependency"], + [425, "Too early"], + [426, "Upgrade required"], + [428, "Precondition required"], + [429, "Too many requests"], + [431, "Request header fields too large"], + [451, "Unavailable for legal reasons"], + [500, "Internal server error"], + [501, "Not implemented"], + [502, "Bad gateway"], + [503, "Service unavailable"], + [504, "Gateway timeout"], + [505, "HTTP version not supported"], + [506, "Variant also negotiates"], + [507, "insufficient storage"], + [508, "Loop detected"], + [510, "Not extended"], + [511, "Network authentication required"], +]); diff --git a/src/application/pages/connectors/$operationId/index.tsx b/src/application/pages/connectors/$operationId/index.tsx index 0604d15ea..610fba01d 100644 --- a/src/application/pages/connectors/$operationId/index.tsx +++ b/src/application/pages/connectors/$operationId/index.tsx @@ -43,7 +43,7 @@ export function Route() {
    {id} {url.pathname + url.search} - + {request?.method} {response?.body?.selection?.errors?.length ?? 0}
    - - - - - - - - - - - {request.debuggingResult.data.map(({ id, request, response }) => { - const url = new URL(request?.url ?? ""); - - return ( - navigate(`requests/${id}`)}> - - - - - + + +
    IDPathStatusMethod -
    - Errors{" "} - - - - - -
    -
    {id}{url.pathname + url.search} - - {request?.method}{response?.body?.selection?.errors?.length ?? 0}
    + + + + + + + - ); - })} - -
    IDPathStatusMethod +
    + Errors{" "} + + + + + +
    +
    + + + {request.debuggingResult.data.map(({ id, request, response }) => { + const url = new URL(request?.url ?? ""); + + return ( + navigate(`requests/${id}`)}> + {id} + {url.pathname + url.search} + + + + {request?.method} + {response?.body?.selection?.errors?.length ?? 0} + + ); + })} + + + + ); } From 1339d8b34511de18c38328f7c0b1fc766449968d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 11:31:00 -0600 Subject: [PATCH 042/114] Add radix accordion --- package-lock.json | 111 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 112 insertions(+) diff --git a/package-lock.json b/package-lock.json index 0be571548..738a2eda0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@graphql-codegen/typescript-resolvers": "^4.1.0", "@headlessui/react": "^2.1.0", "@headlessui/tailwindcss": "^0.2.0", + "@radix-ui/react-accordion": "^1.2.1", "@radix-ui/react-hover-card": "^1.1.1", "@radix-ui/react-select": "^2.1.1", "@radix-ui/react-slot": "^1.1.0", @@ -6550,6 +6551,50 @@ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.1.tgz", + "integrity": "sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collapsible": "1.1.1", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", @@ -6572,6 +6617,72 @@ } } }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz", + "integrity": "sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-presence": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", + "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-collection": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", diff --git a/package.json b/package.json index d476c5456..75c857f36 100755 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "@graphql-codegen/typescript-resolvers": "^4.1.0", "@headlessui/react": "^2.1.0", "@headlessui/tailwindcss": "^0.2.0", + "@radix-ui/react-accordion": "^1.2.1", "@radix-ui/react-hover-card": "^1.1.1", "@radix-ui/react-select": "^2.1.1", "@radix-ui/react-slot": "^1.1.0", From d5066d4e6400d10086e3c037d2c541343026948d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 12:06:37 -0600 Subject: [PATCH 043/114] Add accordion components --- src/application/components/Accordion.tsx | 14 ++++++++++ .../components/AccordionContent.tsx | 20 ++++++++++++++ src/application/components/AccordionIcon.tsx | 7 +++++ src/application/components/AccordionItem.tsx | 8 ++++++ src/application/components/AccordionTitle.tsx | 16 +++++++++++ .../components/AccordionTrigger.tsx | 27 +++++++++++++++++++ 6 files changed, 92 insertions(+) create mode 100644 src/application/components/Accordion.tsx create mode 100644 src/application/components/AccordionContent.tsx create mode 100644 src/application/components/AccordionIcon.tsx create mode 100644 src/application/components/AccordionItem.tsx create mode 100644 src/application/components/AccordionTitle.tsx create mode 100644 src/application/components/AccordionTrigger.tsx diff --git a/src/application/components/Accordion.tsx b/src/application/components/Accordion.tsx new file mode 100644 index 000000000..56c458f74 --- /dev/null +++ b/src/application/components/Accordion.tsx @@ -0,0 +1,14 @@ +import { Root } from "@radix-ui/react-accordion"; +import type { + AccordionSingleProps, + AccordionMultipleProps, +} from "@radix-ui/react-accordion"; +import { twMerge } from "tailwind-merge"; + +type AccordionProps = AccordionSingleProps | AccordionMultipleProps; + +export function Accordion({ className, ...props }: AccordionProps) { + return ( + + ); +} diff --git a/src/application/components/AccordionContent.tsx b/src/application/components/AccordionContent.tsx new file mode 100644 index 000000000..2896d8588 --- /dev/null +++ b/src/application/components/AccordionContent.tsx @@ -0,0 +1,20 @@ +import { Content } from "@radix-ui/react-accordion"; +import type { AccordionContentProps as BaseAccordionContentProps } from "@radix-ui/react-accordion"; +import { twMerge } from "tailwind-merge"; + +type AccordionContentProps = Omit; + +export function AccordionContent({ + className, + ...props +}: AccordionContentProps) { + return ( + + ); +} diff --git a/src/application/components/AccordionIcon.tsx b/src/application/components/AccordionIcon.tsx new file mode 100644 index 000000000..c9e51c073 --- /dev/null +++ b/src/application/components/AccordionIcon.tsx @@ -0,0 +1,7 @@ +import IconChevronDown from "@apollo/icons/default/IconChevronDown.svg"; + +export function AccordionIcon() { + return ( + + ); +} diff --git a/src/application/components/AccordionItem.tsx b/src/application/components/AccordionItem.tsx new file mode 100644 index 000000000..b8651ab09 --- /dev/null +++ b/src/application/components/AccordionItem.tsx @@ -0,0 +1,8 @@ +import { Item } from "@radix-ui/react-accordion"; +import type { AccordionItemProps as BaseAccordionItemProps } from "@radix-ui/react-accordion"; + +type AccordionItemProps = Omit; + +export function AccordionItem(props: AccordionItemProps) { + return ; +} diff --git a/src/application/components/AccordionTitle.tsx b/src/application/components/AccordionTitle.tsx new file mode 100644 index 000000000..7fa7dab58 --- /dev/null +++ b/src/application/components/AccordionTitle.tsx @@ -0,0 +1,16 @@ +import type { ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; + +type AccordionTitleProps = ComponentPropsWithoutRef<"h2">; + +export function AccordionTitle({ className, ...props }: AccordionTitleProps) { + return ( + + ); +} diff --git a/src/application/components/AccordionTrigger.tsx b/src/application/components/AccordionTrigger.tsx new file mode 100644 index 000000000..f25917ed8 --- /dev/null +++ b/src/application/components/AccordionTrigger.tsx @@ -0,0 +1,27 @@ +import { Header, Trigger } from "@radix-ui/react-accordion"; +import type { AccordionTriggerProps as BaseAccordionTriggerProps } from "@radix-ui/react-accordion"; +import { twMerge } from "tailwind-merge"; + +type AccordionTriggerProps = Omit; + +export function AccordionTrigger({ + className, + ...props +}: AccordionTriggerProps) { + return ( +
    + +
    + ); +} From 16956e69821b76a1f2b7c920099ebcd6925e2e8f Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 12:45:49 -0600 Subject: [PATCH 044/114] Create a definition list component --- src/application/components/DefinitionList.tsx | 8 +++++++ .../components/DefinitionListItem.tsx | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/application/components/DefinitionList.tsx create mode 100644 src/application/components/DefinitionListItem.tsx diff --git a/src/application/components/DefinitionList.tsx b/src/application/components/DefinitionList.tsx new file mode 100644 index 000000000..37c6a8f23 --- /dev/null +++ b/src/application/components/DefinitionList.tsx @@ -0,0 +1,8 @@ +import type { ComponentPropsWithoutRef } from "react"; +import { twMerge } from "tailwind-merge"; + +type DlProps = ComponentPropsWithoutRef<"dl">; + +export function DefinitionList({ className, ...props }: DlProps) { + return
    ; +} diff --git a/src/application/components/DefinitionListItem.tsx b/src/application/components/DefinitionListItem.tsx new file mode 100644 index 000000000..d1656da2f --- /dev/null +++ b/src/application/components/DefinitionListItem.tsx @@ -0,0 +1,22 @@ +import type { ComponentPropsWithoutRef, ReactNode } from "react"; +import { twMerge } from "tailwind-merge"; + +interface DefinitionListItemProps + extends Omit, "children"> { + term: string; + value: ReactNode; +} + +export function DefinitionListItem({ + className, + term, + value, + ...props +}: DefinitionListItemProps) { + return ( +
    +
    {term}
    +
    {value}
    +
    + ); +} From adcfc0e45a7654387c37f7b1c0865d6c0b983a66 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 12:47:26 -0600 Subject: [PATCH 045/114] Create a HeadersList component --- src/application/components/HeadersList.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/application/components/HeadersList.tsx diff --git a/src/application/components/HeadersList.tsx b/src/application/components/HeadersList.tsx new file mode 100644 index 000000000..b2a60c052 --- /dev/null +++ b/src/application/components/HeadersList.tsx @@ -0,0 +1,16 @@ +import { DefinitionList } from "./DefinitionList"; +import { DefinitionListItem } from "./DefinitionListItem"; + +interface HeadersListProps { + headers: Array<[string, string]>; +} + +export function HeadersList({ headers }: HeadersListProps) { + return ( + + {headers.map(([name, value], idx) => ( + + ))} + + ); +} From 0fd9654affb6f5a850b2292a22f1f70c4fd630e5 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 12:48:25 -0600 Subject: [PATCH 046/114] Use children as value in DefinitionListItem --- src/application/components/DefinitionListItem.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/application/components/DefinitionListItem.tsx b/src/application/components/DefinitionListItem.tsx index d1656da2f..b1767e99c 100644 --- a/src/application/components/DefinitionListItem.tsx +++ b/src/application/components/DefinitionListItem.tsx @@ -1,22 +1,20 @@ -import type { ComponentPropsWithoutRef, ReactNode } from "react"; +import type { ComponentPropsWithoutRef } from "react"; import { twMerge } from "tailwind-merge"; -interface DefinitionListItemProps - extends Omit, "children"> { +interface DefinitionListItemProps extends ComponentPropsWithoutRef<"div"> { term: string; - value: ReactNode; } export function DefinitionListItem({ + children, className, term, - value, ...props }: DefinitionListItemProps) { return (
    {term}
    -
    {value}
    +
    {children}
    ); } From 299d9f0fa21f1b8ad99f103ba146bac152980c63 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 12:50:17 -0600 Subject: [PATCH 047/114] Add : to dl key --- src/application/components/DefinitionListItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/DefinitionListItem.tsx b/src/application/components/DefinitionListItem.tsx index b1767e99c..6932ff76b 100644 --- a/src/application/components/DefinitionListItem.tsx +++ b/src/application/components/DefinitionListItem.tsx @@ -13,7 +13,7 @@ export function DefinitionListItem({ }: DefinitionListItemProps) { return (
    -
    {term}
    +
    {term}:
    {children}
    ); From bb94da8f4b10328037558d5cf58f5ce07e457213 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 12:50:37 -0600 Subject: [PATCH 048/114] Add connectors request overview tab --- .../components/ConnectorsRequestOverview.tsx | 54 +++++++++++++++++++ .../$operationId/requests/$requestId.tsx | 9 +++- 2 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 src/application/components/ConnectorsRequestOverview.tsx diff --git a/src/application/components/ConnectorsRequestOverview.tsx b/src/application/components/ConnectorsRequestOverview.tsx new file mode 100644 index 000000000..acebb523a --- /dev/null +++ b/src/application/components/ConnectorsRequestOverview.tsx @@ -0,0 +1,54 @@ +import type { ConnectorsDebuggingRequest } from "../../types"; +import { Accordion } from "./Accordion"; +import { AccordionContent } from "./AccordionContent"; +import { AccordionIcon } from "./AccordionIcon"; +import { AccordionItem } from "./AccordionItem"; +import { AccordionTitle } from "./AccordionTitle"; +import { AccordionTrigger } from "./AccordionTrigger"; +import { DefinitionList } from "./DefinitionList"; +import { DefinitionListItem } from "./DefinitionListItem"; +import { HeadersList } from "./HeadersList"; + +interface ConnectorsRequestOverviewProps { + request: ConnectorsDebuggingRequest; +} + +export function ConnectorsRequestOverview({ + request, +}: ConnectorsRequestOverviewProps) { + const { headers } = request; + + return ( + + + + + General + + + + {request.url} + + {request.method} + + + + + + + + Request headers ({headers.length}) + + + {headers.length > 0 ? ( + + ) : ( +
    + No headers +
    + )} +
    +
    +
    + ); +} diff --git a/src/application/pages/connectors/$operationId/requests/$requestId.tsx b/src/application/pages/connectors/$operationId/requests/$requestId.tsx index fc0ce721f..0b61e4e3e 100644 --- a/src/application/pages/connectors/$operationId/requests/$requestId.tsx +++ b/src/application/pages/connectors/$operationId/requests/$requestId.tsx @@ -4,6 +4,7 @@ import { useMemo } from "react"; import { Tabs } from "../../../../components/Tabs"; import { JSONTreeViewer } from "../../../../components/JSONTreeViewer"; import IconStatusDot from "@apollo/icons/default/IconStatusDot.svg"; +import { ConnectorsRequestOverview } from "../../../../components/ConnectorsRequestOverview"; export function Route() { const params = useParams(); @@ -21,7 +22,7 @@ export function Route() { const selectionErrorCount = response?.body.selection?.errors.length ?? 0; return ( - + Request overview Response overview @@ -36,7 +37,11 @@ export function Route() { -
    URL: {data.request?.url}
    + {data.request ? ( + + ) : ( + "Empty state here" + )}
    Status code: {data.response?.status}
    From 487333b32da462f13ac9a4ddf07618dca848ebb8 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:03:18 -0600 Subject: [PATCH 049/114] Add animation to connectors content --- .../components/AccordionContent.tsx | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/src/application/components/AccordionContent.tsx b/src/application/components/AccordionContent.tsx index 2896d8588..021b9154d 100644 --- a/src/application/components/AccordionContent.tsx +++ b/src/application/components/AccordionContent.tsx @@ -1,5 +1,8 @@ import { Content } from "@radix-ui/react-accordion"; import type { AccordionContentProps as BaseAccordionContentProps } from "@radix-ui/react-accordion"; +import { AnimatePresence, motion } from "framer-motion"; +import type { ReactNode } from "react"; +import { forwardRef, type ComponentPropsWithoutRef } from "react"; import { twMerge } from "tailwind-merge"; type AccordionContentProps = Omit; @@ -9,12 +12,40 @@ export function AccordionContent({ ...props }: AccordionContentProps) { return ( - + + + ); } + +type AnimatedContentProps = ComponentPropsWithoutRef; + +const AnimatedContent = forwardRef( + ({ className, ...props }) => { + const show = (props as Record)["data-state"] === "open"; + + return ( + + {show && ( + +
    + {props.children as ReactNode} +
    +
    + )} +
    + ); + } +); From c33ada533a0ca0d66d277b95810bfa95032f7d1a Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:03:28 -0600 Subject: [PATCH 050/114] Default open general accordion --- src/application/components/ConnectorsRequestOverview.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/ConnectorsRequestOverview.tsx b/src/application/components/ConnectorsRequestOverview.tsx index acebb523a..4efe3aa33 100644 --- a/src/application/components/ConnectorsRequestOverview.tsx +++ b/src/application/components/ConnectorsRequestOverview.tsx @@ -19,7 +19,7 @@ export function ConnectorsRequestOverview({ const { headers } = request; return ( - + From e21ead0943aac7b00906d9898ab246b5871cb17f Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:04:37 -0600 Subject: [PATCH 051/114] Expand all request body nodes initially --- .../pages/connectors/$operationId/requests/$requestId.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/application/pages/connectors/$operationId/requests/$requestId.tsx b/src/application/pages/connectors/$operationId/requests/$requestId.tsx index 0b61e4e3e..2a7fe04d0 100644 --- a/src/application/pages/connectors/$operationId/requests/$requestId.tsx +++ b/src/application/pages/connectors/$operationId/requests/$requestId.tsx @@ -53,6 +53,7 @@ export function Route() { hideRoot={!Array.isArray(response.body.content)} className="[&>li]:!pt-0" data={response.body.content} + shouldExpandNodeInitially={() => true} /> ) : ( String(response.body.content) From 1356f9c29350388019555b217b6d7fd2ffb8804c Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:14:16 -0600 Subject: [PATCH 052/114] Fix HeadersList not showing value --- src/application/components/HeadersList.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/application/components/HeadersList.tsx b/src/application/components/HeadersList.tsx index b2a60c052..0dbfd323d 100644 --- a/src/application/components/HeadersList.tsx +++ b/src/application/components/HeadersList.tsx @@ -9,7 +9,9 @@ export function HeadersList({ headers }: HeadersListProps) { return ( {headers.map(([name, value], idx) => ( - + + {value} + ))} ); From 8948086368f2ed313137649d0ab07f2a2960a470 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:16:18 -0600 Subject: [PATCH 053/114] Don't wrap header names --- src/application/components/HeadersList.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/application/components/HeadersList.tsx b/src/application/components/HeadersList.tsx index 0dbfd323d..c19d059f8 100644 --- a/src/application/components/HeadersList.tsx +++ b/src/application/components/HeadersList.tsx @@ -9,7 +9,11 @@ export function HeadersList({ headers }: HeadersListProps) { return ( {headers.map(([name, value], idx) => ( - + {value} ))} From 246355671294bc291bd24239fb7f1799d8de24b6 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:16:26 -0600 Subject: [PATCH 054/114] Tweak animation on AccordionContent --- .../components/AccordionContent.tsx | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/application/components/AccordionContent.tsx b/src/application/components/AccordionContent.tsx index 021b9154d..c0006f6e4 100644 --- a/src/application/components/AccordionContent.tsx +++ b/src/application/components/AccordionContent.tsx @@ -20,6 +20,10 @@ export function AccordionContent({ type AnimatedContentProps = ComponentPropsWithoutRef; +const EASINGS = { + ease: [0.25, 0.1, 0.25, 1], +}; + const AnimatedContent = forwardRef( ({ className, ...props }) => { const show = (props as Record)["data-state"] === "open"; @@ -30,14 +34,29 @@ const AnimatedContent = forwardRef(
    From 779038fb3e85b6fa690c334d30d1156c67c3d4f5 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:16:36 -0600 Subject: [PATCH 055/114] Show connectors response overview --- .../components/ConnectorsResponseOverview.tsx | 55 +++++++++++++++++++ .../$operationId/requests/$requestId.tsx | 9 ++- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/application/components/ConnectorsResponseOverview.tsx diff --git a/src/application/components/ConnectorsResponseOverview.tsx b/src/application/components/ConnectorsResponseOverview.tsx new file mode 100644 index 000000000..9d5e7d591 --- /dev/null +++ b/src/application/components/ConnectorsResponseOverview.tsx @@ -0,0 +1,55 @@ +import type { ConnectorsDebuggingResponse } from "../../types"; +import { Accordion } from "./Accordion"; +import { AccordionContent } from "./AccordionContent"; +import { AccordionIcon } from "./AccordionIcon"; +import { AccordionItem } from "./AccordionItem"; +import { AccordionTitle } from "./AccordionTitle"; +import { AccordionTrigger } from "./AccordionTrigger"; +import { DefinitionList } from "./DefinitionList"; +import { DefinitionListItem } from "./DefinitionListItem"; +import { HeadersList } from "./HeadersList"; +import { HTTPStatusBadge } from "./HTTPStatusBadge"; + +interface ConnectorsResponseOverviewProps { + response: ConnectorsDebuggingResponse; +} + +export function ConnectorsResponseOverview({ + response, +}: ConnectorsResponseOverviewProps) { + console.log(response.headers); + return ( + + + + + General + + + + + + + + + + + + + + Response headers ({response.headers.length}) + + + + {response.headers.length > 0 ? ( + + ) : ( +
    + No headers +
    + )} +
    +
    +
    + ); +} diff --git a/src/application/pages/connectors/$operationId/requests/$requestId.tsx b/src/application/pages/connectors/$operationId/requests/$requestId.tsx index 2a7fe04d0..f474a90da 100644 --- a/src/application/pages/connectors/$operationId/requests/$requestId.tsx +++ b/src/application/pages/connectors/$operationId/requests/$requestId.tsx @@ -5,6 +5,7 @@ import { Tabs } from "../../../../components/Tabs"; import { JSONTreeViewer } from "../../../../components/JSONTreeViewer"; import IconStatusDot from "@apollo/icons/default/IconStatusDot.svg"; import { ConnectorsRequestOverview } from "../../../../components/ConnectorsRequestOverview"; +import { ConnectorsResponseOverview } from "../../../../components/ConnectorsResponseOverview"; export function Route() { const params = useParams(); @@ -44,7 +45,11 @@ export function Route() { )} -
    Status code: {data.response?.status}
    + {data.response ? ( + + ) : ( + "Empty state here" + )}
    {response?.body && ( @@ -60,7 +65,7 @@ export function Route() { )} )} - +
    Mapping:
    From e4a1748cfc0b9e9b50186e1117da9b62825643fc Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:26:24 -0600 Subject: [PATCH 056/114] Extract ConnectorsBody component --- src/application/components/ConnectorsBody.tsx | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/application/components/ConnectorsBody.tsx diff --git a/src/application/components/ConnectorsBody.tsx b/src/application/components/ConnectorsBody.tsx new file mode 100644 index 000000000..96c3adcea --- /dev/null +++ b/src/application/components/ConnectorsBody.tsx @@ -0,0 +1,19 @@ +import type { ConnectorsDebuggingBody } from "../../types"; +import { JSONTreeViewer } from "./JSONTreeViewer"; + +interface ConnectorsBodyProps { + body: ConnectorsDebuggingBody; +} + +export function ConnectorsBody({ body }: ConnectorsBodyProps) { + return body.kind === "json" ? ( + true} + /> + ) : ( + String(body.content) + ); +} From 873d3ffd80be3a9bdd0e02840c1aedfdfb99a952 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:26:33 -0600 Subject: [PATCH 057/114] Rename Body to ConnectorsDebuggingBody --- src/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/types.ts b/src/types.ts index 57d9c0783..7b8d0ac6e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -55,7 +55,7 @@ export interface ConnectorsDebuggingRequest { url: string; method: string; headers: [string, string][]; - body: Body | null; + body: ConnectorsDebuggingBody | null; } interface SelectionError { @@ -64,7 +64,7 @@ interface SelectionError { count: number; } -export interface Body { +export interface ConnectorsDebuggingBody { kind: string; content: Content; } @@ -81,7 +81,7 @@ export interface SelectionMappingResponse { export interface ConnectorsDebuggingResponse { status: number; headers: [string, string][]; - body: Body & { + body: ConnectorsDebuggingBody & { selection: SelectionMappingResponse; }; } From 28a40bb5d2d2ef8496b451f1b2e141c60c71e4bc Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:27:30 -0600 Subject: [PATCH 058/114] Add an empty state component --- src/application/assets/icon-galaxy.svg | 30 +++++++++++++++++++ .../components/ConnectorsEmptyState.tsx | 15 ++++++++++ 2 files changed, 45 insertions(+) create mode 100644 src/application/assets/icon-galaxy.svg create mode 100644 src/application/components/ConnectorsEmptyState.tsx diff --git a/src/application/assets/icon-galaxy.svg b/src/application/assets/icon-galaxy.svg new file mode 100644 index 000000000..56b6ea6b9 --- /dev/null +++ b/src/application/assets/icon-galaxy.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/application/components/ConnectorsEmptyState.tsx b/src/application/components/ConnectorsEmptyState.tsx new file mode 100644 index 000000000..6537a13de --- /dev/null +++ b/src/application/components/ConnectorsEmptyState.tsx @@ -0,0 +1,15 @@ +import type { ReactNode } from "react"; +import IconGalaxy from "../assets/icon-galaxy.svg"; + +interface ConnectorsEmptyStateProps { + children?: ReactNode; +} + +export function ConnectorsEmptyState({ children }: ConnectorsEmptyStateProps) { + return ( +
    + +

    {children}

    +
    + ); +} From 578806de23a57c0b470f0b08ef5998b864d87981 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:28:29 -0600 Subject: [PATCH 059/114] Update to use empty state and body components --- .../$operationId/requests/$requestId.tsx | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/application/pages/connectors/$operationId/requests/$requestId.tsx b/src/application/pages/connectors/$operationId/requests/$requestId.tsx index f474a90da..2ab58eadf 100644 --- a/src/application/pages/connectors/$operationId/requests/$requestId.tsx +++ b/src/application/pages/connectors/$operationId/requests/$requestId.tsx @@ -2,10 +2,11 @@ import { useParams } from "react-router-dom"; import { useRequest } from "../../$operationId"; import { useMemo } from "react"; import { Tabs } from "../../../../components/Tabs"; -import { JSONTreeViewer } from "../../../../components/JSONTreeViewer"; import IconStatusDot from "@apollo/icons/default/IconStatusDot.svg"; import { ConnectorsRequestOverview } from "../../../../components/ConnectorsRequestOverview"; import { ConnectorsResponseOverview } from "../../../../components/ConnectorsResponseOverview"; +import { ConnectorsBody } from "../../../../components/ConnectorsBody"; +import { ConnectorsEmptyState } from "../../../../components/ConnectorsEmptyState"; export function Route() { const params = useParams(); @@ -26,10 +27,11 @@ export function Route() { Request overview - Response overview - {response?.body && ( - Response body + {!!data.request?.body && ( + Request body )} + Response overview + Response body Mapping {selectionErrorCount > 0 && ( @@ -41,30 +43,30 @@ export function Route() { {data.request ? ( ) : ( - "Empty state here" + + No request details to show + )}
    + + {data.request?.body && } + {data.response ? ( ) : ( - "Empty state here" + + No response details to show + + )} + + + {response?.body ? ( + + ) : ( + No response body to show )} - {response?.body && ( - - {response.body.kind === "json" ? ( - true} - /> - ) : ( - String(response.body.content) - )} - - )}
    Mapping:
    From b6d10f6333f695c123c972acc1e28b44578782cb Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:45:34 -0600 Subject: [PATCH 060/114] Add support for destructive button --- src/application/components/Button.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/application/components/Button.tsx b/src/application/components/Button.tsx index 6634dd88a..e601def27 100644 --- a/src/application/components/Button.tsx +++ b/src/application/components/Button.tsx @@ -43,6 +43,13 @@ const button = cva( { variants: { variant: { + destructive: [ + "text-white", + "bg-button-destructive", + "dark:bg-button-destructive-dark", + "hover:bg-button-destructiveHover", + "dark:hover:bg-button-destructiveHover-dark", + ], hidden: [ "text-primary", "dark:text-primary-dark", From d13b14b82e868329fab13cc4fa3ac5824052ae3b Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 14:47:57 -0600 Subject: [PATCH 061/114] Add support for attached buttons --- src/application/components/Button.tsx | 9 +++++++++ src/application/components/ButtonGroup.tsx | 18 ++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/application/components/Button.tsx b/src/application/components/Button.tsx index e601def27..b4949004b 100644 --- a/src/application/components/Button.tsx +++ b/src/application/components/Button.tsx @@ -39,6 +39,7 @@ const button = cva( "disabled:cursor-not-allowed", "transition-colors", "duration-200", + "group-[[data-attached=true]]/button-group:rounded-none", ], { variants: { @@ -79,6 +80,8 @@ const button = cva( "hover:dark:bg-button-secondaryHover-dark", "active:bg-selected", "active:dark:bg-selected-dark", + "group-[[data-attached=true]]/button-group:border-r-0", + "group-[[data-attached=true]]/button-group:last:border-r", ], }, size: { @@ -88,6 +91,8 @@ const button = cva( "text-sm", "font-semibold", "has-[>svg:only-child]:p-1.5", + "group-[[data-attached=true]]/button-group:first:rounded-l", + "group-[[data-attached=true]]/button-group:last:rounded-r", ], sm: [ "py-2", @@ -96,6 +101,8 @@ const button = cva( "text-sm", "font-semibold", "has-[>svg:only-child]:p-2", + "group-[[data-attached=true]]/button-group:first:rounded-l", + "group-[[data-attached=true]]/button-group:last:rounded-r", ], md: [ "py-2", @@ -104,6 +111,8 @@ const button = cva( "text-md", "font-semibold", "has-[>svg:only-child]:p-3", + "group-[[data-attached=true]]/button-group:first:rounded-l-lg", + "group-[[data-attached=true]]/button-group:last:rounded-r-lg", ], }, }, diff --git a/src/application/components/ButtonGroup.tsx b/src/application/components/ButtonGroup.tsx index d1d66ab6e..224b18bfb 100644 --- a/src/application/components/ButtonGroup.tsx +++ b/src/application/components/ButtonGroup.tsx @@ -2,12 +2,26 @@ import type { ReactNode } from "react"; import clsx from "clsx"; interface ButtonGroupProps { + attached?: boolean; className?: string; children: ReactNode; } -export function ButtonGroup({ className, children }: ButtonGroupProps) { +export function ButtonGroup({ + attached, + className, + children, +}: ButtonGroupProps) { return ( -
    {children}
    +
    + {children} +
    ); } From d0017505a136c259ef6437c5383ee80177a18de4 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 15:04:41 -0600 Subject: [PATCH 062/114] Add height for button --- src/application/components/Button.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/application/components/Button.tsx b/src/application/components/Button.tsx index b4949004b..37429ed80 100644 --- a/src/application/components/Button.tsx +++ b/src/application/components/Button.tsx @@ -32,6 +32,7 @@ const button = cva( "focus:dark:ring-offset-primary-dark", "focus:ring-focused", "focus:dark:ring-focused-dark", + "focus:z-10", "disabled:bg-button-disabled", "disabled:dark:bg-button-disabled-dark", "disabled:text-disabled", @@ -95,6 +96,7 @@ const button = cva( "group-[[data-attached=true]]/button-group:last:rounded-r", ], sm: [ + "h-8", "py-2", "px-3", "rounded", From 4b0a277620d21c9fb5a271128cf398bcf8caa6c9 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 15:05:56 -0600 Subject: [PATCH 063/114] Add connectors response mapping --- .../components/ConnectorsResponseMapping.tsx | 147 ++++++++++++++++++ .../$operationId/requests/$requestId.tsx | 12 +- 2 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 src/application/components/ConnectorsResponseMapping.tsx diff --git a/src/application/components/ConnectorsResponseMapping.tsx b/src/application/components/ConnectorsResponseMapping.tsx new file mode 100644 index 000000000..0a1aa8730 --- /dev/null +++ b/src/application/components/ConnectorsResponseMapping.tsx @@ -0,0 +1,147 @@ +import { useState } from "react"; +import IconConnectorsResult from "@apollo/icons/small/IconConnectorsResult.svg"; +import IconConnectorsSource from "@apollo/icons/small/IconConnectorsSource.svg"; +import IconConnectorsTransformation from "@apollo/icons/small/IconConnectorsTransformation.svg"; +import IconError from "@apollo/icons/small/IconError.svg"; +import type { SelectionMappingResponse } from "../../types"; +import { ButtonGroup } from "./ButtonGroup"; +import { Tooltip } from "./Tooltip"; +import { Button } from "./Button"; +import { twMerge } from "tailwind-merge"; +import { ConnectorsBody } from "./ConnectorsBody"; +import { Card } from "./Card"; +import { ConnectorsEmptyState } from "./ConnectorsEmptyState"; +import { Table } from "./Table"; +import { Tbody } from "./Tbody"; +import { Tr } from "./Tr"; +import { Td } from "./Td"; +import { Thead } from "./Thead"; +import { Th } from "./Th"; +import { CardBody } from "./CardBody"; + +interface ConnectorsResponseMappingProps { + selection: SelectionMappingResponse; + showErrorViewFirst?: boolean; +} + +type ActiveView = "source" | "result" | "transformed" | "errors"; + +export function ConnectorsResponseMapping({ + selection, + showErrorViewFirst, +}: ConnectorsResponseMappingProps) { + const [activeView, setActiveView] = useState( + showErrorViewFirst ? "errors" : "source" + ); + + return ( +
    +
    +

    {HEADINGS_MAP[activeView]}

    + + + + + +
    + {activeView === "errors" ? ( + + ) : ( + + )} +
    + ); +} + +const ErrorsView = ({ + errors, +}: { + errors: SelectionMappingResponse["errors"]; +}) => + errors.length ? ( + + + + + + + + + + {errors.map((error, idx) => ( + + + + + + ))} + +
    MessagePathCount
    {error.message} + {error.path} + {error.count}
    +
    +
    + ) : ( + No errors to display + ); + +const HEADINGS_MAP: Record = { + errors: "Errors", + result: "Result", + source: "Original selection", + transformed: "Runtime selection", +}; diff --git a/src/application/pages/connectors/$operationId/requests/$requestId.tsx b/src/application/pages/connectors/$operationId/requests/$requestId.tsx index 2ab58eadf..afe7554fb 100644 --- a/src/application/pages/connectors/$operationId/requests/$requestId.tsx +++ b/src/application/pages/connectors/$operationId/requests/$requestId.tsx @@ -7,6 +7,7 @@ import { ConnectorsRequestOverview } from "../../../../components/ConnectorsRequ import { ConnectorsResponseOverview } from "../../../../components/ConnectorsResponseOverview"; import { ConnectorsBody } from "../../../../components/ConnectorsBody"; import { ConnectorsEmptyState } from "../../../../components/ConnectorsEmptyState"; +import { ConnectorsResponseMapping } from "../../../../components/ConnectorsResponseMapping"; export function Route() { const params = useParams(); @@ -21,7 +22,8 @@ export function Route() { ); const response = data.response; - const selectionErrorCount = response?.body.selection?.errors.length ?? 0; + const selection = data.response?.body.selection; + const selectionErrorCount = selection?.errors.length ?? 0; return ( @@ -68,7 +70,13 @@ export function Route() { )} -
    Mapping:
    + {selection ? ( + + ) : ( + + No selection mapping to show + + )}
    ); From dcaca839ce620dd097617f44dc0d3b1aab1adac6 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 15:11:49 -0600 Subject: [PATCH 064/114] Fix view for selection source --- .../components/ConnectorsResponseMapping.tsx | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/application/components/ConnectorsResponseMapping.tsx b/src/application/components/ConnectorsResponseMapping.tsx index 0a1aa8730..6fb506a37 100644 --- a/src/application/components/ConnectorsResponseMapping.tsx +++ b/src/application/components/ConnectorsResponseMapping.tsx @@ -37,7 +37,9 @@ export function ConnectorsResponseMapping({ return (
    -

    {HEADINGS_MAP[activeView]}

    +

    + {HEADINGS_MAP[activeView]} +

    ); } -const ErrorsView = ({ +function Selection({ source }: { source: string }) { + return
    {source}
    ; +} + +function ErrorsView({ errors, }: { errors: SelectionMappingResponse["errors"]; -}) => - errors.length ? ( +}) { + return errors.length ? ( @@ -138,6 +143,7 @@ const ErrorsView = ({ ) : ( No errors to display ); +} const HEADINGS_MAP: Record = { errors: "Errors", From 7e0390c4e1a137ca8bfbf9af72bef0bd13b91bca Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 15:30:41 -0600 Subject: [PATCH 065/114] WIP show connectors in queries tab --- .../components/Queries/Queries.tsx | 68 ++++++++++++++++++- .../components/QueryLayout/QueryLayout.tsx | 2 +- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/application/components/Queries/Queries.tsx b/src/application/components/Queries/Queries.tsx index 6585c322a..c7a8a643f 100644 --- a/src/application/components/Queries/Queries.tsx +++ b/src/application/components/Queries/Queries.tsx @@ -1,6 +1,6 @@ import { useMemo, useState } from "react"; import type { TypedDocumentNode } from "@apollo/client"; -import { NetworkStatus, gql, useQuery } from "@apollo/client"; +import { NetworkStatus, gql, useQuery, useReactiveVar } from "@apollo/client"; import { isNetworkRequestInFlight } from "@apollo/client/core/networkStatus"; import { List } from "../List"; import { ListItem } from "../ListItem"; @@ -26,11 +26,23 @@ import { SearchField } from "../SearchField"; import HighlightMatch from "../HighlightMatch"; import { PageSpinner } from "../PageSpinner"; import { isIgnoredError } from "../../utilities/ignoredErrors"; +import { connectorsRequestsVar } from "../../vars"; +import { canonicalStringify } from "@apollo/client/cache"; +import { Card } from "../Card"; +import { CardBody } from "../CardBody"; +import { Thead } from "../Thead"; +import { Table } from "../Table"; +import { Tr } from "../Tr"; +import { Th } from "../Th"; +import { Tbody } from "../Tbody"; +import { Td } from "../Td"; +import { useLocation, useNavigate } from "react-router-dom"; enum QueryTabs { Variables = "Variables", CachedData = "CachedData", Options = "Options", + Connectors = "Connectors", } export const GET_QUERIES: TypedDocumentNode = @@ -71,6 +83,8 @@ const STABLE_EMPTY_QUERIES: Array< export const Queries = ({ clientId, explorerIFrame }: QueriesProps) => { const [selected, setSelected] = useState("1"); const [searchTerm, setSearchTerm] = useState(""); + const connectorsRequests = useReactiveVar(connectorsRequestsVar); + const navigate = useNavigate(); const { loading, error, data, startPolling, stopPolling } = useQuery( GET_QUERIES, @@ -227,6 +241,9 @@ export const Queries = ({ clientId, explorerIFrame }: QueriesProps) => { Cached Data Options + + Connectors + { data={selectedQuery?.options ?? {}} /> + +
    + {connectorsRequests + .filter((data) => { + return ( + data.query === selectedQuery?.queryString && + canonicalStringify(data.variables) === + canonicalStringify(selectedQuery.variables) + ); + }) + .map((data) => { + return ( + + +
    + + + + + + + + {data.debuggingResult.data.map((result) => { + return ( + { + console.log( + "navigate", + `/connectors/${data.id}/requests/${result.id}` + ); + navigate( + `/connectors/${data.id}/requests/${result.id}` + ); + }} + > + + + + ); + })} + +
    IDURL
    {result.id}{result.request?.url}
    +
    +
    + ); + })} +
    + )} diff --git a/src/application/components/QueryLayout/QueryLayout.tsx b/src/application/components/QueryLayout/QueryLayout.tsx index 96b63c04d..fdea12cff 100644 --- a/src/application/components/QueryLayout/QueryLayout.tsx +++ b/src/application/components/QueryLayout/QueryLayout.tsx @@ -18,7 +18,7 @@ export function QueryLayout({ children }: QueryLayoutProps) { {children} From 4d3267bed08491c185f824f6c9d6f7e8611ff5ce Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 16:05:59 -0600 Subject: [PATCH 066/114] Add some additional tooltip fixes --- src/application/components/Tooltip/Tooltip.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/application/components/Tooltip/Tooltip.tsx b/src/application/components/Tooltip/Tooltip.tsx index c9c6b2568..b516fb37b 100644 --- a/src/application/components/Tooltip/Tooltip.tsx +++ b/src/application/components/Tooltip/Tooltip.tsx @@ -6,6 +6,7 @@ interface TooltipProps { content: ReactNode; children?: ReactNode; delayDuration?: number; + disableHoverableContent?: boolean; side?: "top" | "bottom" | "left" | "right"; } @@ -13,15 +14,19 @@ export function Tooltip({ content, children, delayDuration, + disableHoverableContent, side = "bottom", }: TooltipProps) { return ( - + {children} {content} From b3e29d0c98375e82b07cc981a24b93b8abf47b31 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 16:06:09 -0600 Subject: [PATCH 067/114] Ensure Tr uses forwardRef --- src/application/components/Tr.tsx | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/application/components/Tr.tsx b/src/application/components/Tr.tsx index 6c3376c37..ec6e9c0ca 100644 --- a/src/application/components/Tr.tsx +++ b/src/application/components/Tr.tsx @@ -1,16 +1,19 @@ -import type { ComponentPropsWithoutRef } from "react"; +import { forwardRef, type ComponentPropsWithoutRef } from "react"; import { twMerge } from "tailwind-merge"; type TrProps = ComponentPropsWithoutRef<"tr">; -export function Tr({ className, ...props }: TrProps) { - return ( - - ); -} +export const Tr = forwardRef( + ({ className, ...props }, ref) => { + return ( + + ); + } +); From e6279e3d22249072dbf93b122200e80bed7e66de Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 16:06:16 -0600 Subject: [PATCH 068/114] Show additional info in table for Queries --- .../components/Queries/Queries.tsx | 105 ++++++++++-------- .../components/QueryLayout/QueryLayout.tsx | 2 +- 2 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/application/components/Queries/Queries.tsx b/src/application/components/Queries/Queries.tsx index c7a8a643f..31e459f15 100644 --- a/src/application/components/Queries/Queries.tsx +++ b/src/application/components/Queries/Queries.tsx @@ -36,7 +36,8 @@ import { Tr } from "../Tr"; import { Th } from "../Th"; import { Tbody } from "../Tbody"; import { Td } from "../Td"; -import { useLocation, useNavigate } from "react-router-dom"; +import { useNavigate } from "react-router-dom"; +import { HTTPStatusBadge } from "../HTTPStatusBadge"; enum QueryTabs { Variables = "Variables", @@ -127,6 +128,16 @@ export const Queries = ({ clientId, explorerIFrame }: QueriesProps) => { return queries.filter((query) => query.name && regex.test(query.name)); }, [searchTerm, queries]); + const lastConnectorsRequest = connectorsRequests + .filter((data) => { + return ( + data.query === selectedQuery?.queryString && + canonicalStringify(data.variables) === + canonicalStringify(selectedQuery.variables) + ); + }) + .at(-1); + return ( @@ -272,53 +283,51 @@ export const Queries = ({ clientId, explorerIFrame }: QueriesProps) => { /> -
    - {connectorsRequests - .filter((data) => { - return ( - data.query === selectedQuery?.queryString && - canonicalStringify(data.variables) === - canonicalStringify(selectedQuery.variables) - ); - }) - .map((data) => { - return ( - - - - - - - - - - - {data.debuggingResult.data.map((result) => { - return ( - { - console.log( - "navigate", - `/connectors/${data.id}/requests/${result.id}` - ); - navigate( - `/connectors/${data.id}/requests/${result.id}` - ); - }} - > - - - - ); - })} - -
    IDURL
    {result.id}{result.request?.url}
    -
    -
    - ); - })} -
    + {lastConnectorsRequest && ( + + + + + + + + + + + + {lastConnectorsRequest.debuggingResult.data.map( + (result) => { + return ( + + { + navigate( + `/connectors/${lastConnectorsRequest.id}/requests/${result.id}` + ); + }} + > + + + + + + ); + } + )} + +
    MethodStatusURL
    {result.request?.method} + + {result.request?.url}
    +
    +
    + )}
    diff --git a/src/application/components/QueryLayout/QueryLayout.tsx b/src/application/components/QueryLayout/QueryLayout.tsx index fdea12cff..88f07d1d2 100644 --- a/src/application/components/QueryLayout/QueryLayout.tsx +++ b/src/application/components/QueryLayout/QueryLayout.tsx @@ -18,7 +18,7 @@ export function QueryLayout({ children }: QueryLayoutProps) { {children} From dbac13a79e5b9cffd994ec074c7a8ee54506946e Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 16:22:11 -0600 Subject: [PATCH 069/114] Add forwardRef for card --- src/application/components/Card.tsx | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/application/components/Card.tsx b/src/application/components/Card.tsx index 86d27fe7a..15b40489b 100644 --- a/src/application/components/Card.tsx +++ b/src/application/components/Card.tsx @@ -1,6 +1,6 @@ import { cva } from "class-variance-authority"; import type { ComponentPropsWithoutRef } from "react"; -import { useMemo } from "react"; +import { forwardRef, useMemo } from "react"; import { CardProvider } from "./CardContext"; import { twMerge } from "tailwind-merge"; @@ -34,12 +34,16 @@ const card = cva( } ); -export function Card({ children, className, variant = "outline" }: CardProps) { - const context = useMemo(() => ({ variant }), [variant]); +export const Card = forwardRef( + ({ children, className, variant = "outline" }, ref) => { + const context = useMemo(() => ({ variant }), [variant]); - return ( - -
    {children}
    -
    - ); -} + return ( + +
    + {children} +
    +
    + ); + } +); From fd96c66d69d67e30d29100e5fc317eaee72eb802 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 16:32:25 -0600 Subject: [PATCH 070/114] Use code block for selection --- src/application/components/ConnectorsResponseMapping.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/application/components/ConnectorsResponseMapping.tsx b/src/application/components/ConnectorsResponseMapping.tsx index 6fb506a37..18984920f 100644 --- a/src/application/components/ConnectorsResponseMapping.tsx +++ b/src/application/components/ConnectorsResponseMapping.tsx @@ -18,6 +18,7 @@ import { Td } from "./Td"; import { Thead } from "./Thead"; import { Th } from "./Th"; import { CardBody } from "./CardBody"; +import { CodeBlock } from "./CodeBlock"; interface ConnectorsResponseMappingProps { selection: SelectionMappingResponse; @@ -85,7 +86,7 @@ export function ConnectorsResponseMapping({ "size-4", activeView !== "errors" && selection.errors.length && - "!text-icon-error" + "text-icon-error dark:text-icon-error" )} /> } @@ -109,7 +110,7 @@ export function ConnectorsResponseMapping({ } function Selection({ source }: { source: string }) { - return
    {source}
    ; + return ; } function ErrorsView({ From bb64c6afa9c17052b3d2ffda66ccda354471420d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 16:32:38 -0600 Subject: [PATCH 071/114] Fix size of title in connectors page --- src/application/pages/connectors/$operationId.tsx | 7 +++++-- src/application/pages/connectors/index.tsx | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/application/pages/connectors/$operationId.tsx b/src/application/pages/connectors/$operationId.tsx index 7f8c637be..c965fb05a 100644 --- a/src/application/pages/connectors/$operationId.tsx +++ b/src/application/pages/connectors/$operationId.tsx @@ -23,7 +23,7 @@ export function Route() { if (!request) { return ( -

    +

    All requests

    Connectors request not found @@ -34,7 +34,7 @@ export function Route() { return ( <> -

    +

    All requests

    @@ -46,6 +46,9 @@ export function Route() { minSize={25} className="h-full p-4 flex flex-col gap-2" > +

    + Query +

    Variables diff --git a/src/application/pages/connectors/index.tsx b/src/application/pages/connectors/index.tsx index 4414836e0..5cc0be518 100644 --- a/src/application/pages/connectors/index.tsx +++ b/src/application/pages/connectors/index.tsx @@ -13,7 +13,7 @@ export function Route() { return ( -

    +

    All requests

    From ed86d922b307502e2d3085318ab0649a3e201339 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 17:04:58 -0600 Subject: [PATCH 072/114] Add icon to empty message. Allow custom title/description --- src/application/assets/observatory.svg | 13 ++++++++++ src/application/components/EmptyMessage.tsx | 28 ++++++++++++++++----- 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 src/application/assets/observatory.svg diff --git a/src/application/assets/observatory.svg b/src/application/assets/observatory.svg new file mode 100644 index 000000000..c8d7858c7 --- /dev/null +++ b/src/application/assets/observatory.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/application/components/EmptyMessage.tsx b/src/application/components/EmptyMessage.tsx index e6facc5fb..7da97f98e 100644 --- a/src/application/components/EmptyMessage.tsx +++ b/src/application/components/EmptyMessage.tsx @@ -1,18 +1,34 @@ import { clsx } from "clsx"; +import IconObservatory from "../assets/observatory.svg"; +import { cloneElement, type ReactElement, type ReactNode } from "react"; interface EmptyMessageProps { + icon?: ReactElement<{ className?: string }>; className?: string; + title?: string; + children?: ReactNode; } -export function EmptyMessage({ className }: EmptyMessageProps) { +export function EmptyMessage({ + icon = , + className, + title, + children, +}: EmptyMessageProps) { return ( -
    -

    - 👋 Welcome to Apollo Client Devtools +
    + {cloneElement(icon, { className: clsx("w-48", icon.props.className) })} +

    + {title || "👋 Welcome to Apollo Client Devtools"}

    - Start interacting with your interface to see data reflected in this - space + {children || + "Start interacting with your interface to see data reflected in this space"}
    ); From 80ab2273485727de63b1e54020cfc3b405168171 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 17:10:39 -0600 Subject: [PATCH 073/114] Switch to focus-visible on Button --- src/application/components/Button.tsx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/application/components/Button.tsx b/src/application/components/Button.tsx index 37429ed80..1fe875d56 100644 --- a/src/application/components/Button.tsx +++ b/src/application/components/Button.tsx @@ -26,13 +26,13 @@ const button = cva( "flex", "gap-2", "outline-none", - "focus:ring-3", - "focus:ring-offset-3", - "focus:ring-offset-primary", - "focus:dark:ring-offset-primary-dark", - "focus:ring-focused", - "focus:dark:ring-focused-dark", - "focus:z-10", + "focus-visible:ring-3", + "focus-visible:ring-offset-3", + "focus-visible:ring-offset-primary", + "focus-visible:dark:ring-offset-primary-dark", + "focus-visible:ring-focused", + "focus-visible:dark:ring-focused-dark", + "focus-visible:z-10", "disabled:bg-button-disabled", "disabled:dark:bg-button-disabled-dark", "disabled:text-disabled", From 861a6c7bd10fcfda725808c28e6ac5d5cc332dbf Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 17:10:47 -0600 Subject: [PATCH 074/114] Left align the error description --- src/application/components/EmptyMessage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/EmptyMessage.tsx b/src/application/components/EmptyMessage.tsx index 7da97f98e..bf54c834f 100644 --- a/src/application/components/EmptyMessage.tsx +++ b/src/application/components/EmptyMessage.tsx @@ -26,7 +26,7 @@ export function EmptyMessage({

    {title || "👋 Welcome to Apollo Client Devtools"}

    -
    +
    {children || "Start interacting with your interface to see data reflected in this space"}
    From b71c807046e4f71c5d9199356c5ff99f385d9a3f Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 17:11:03 -0600 Subject: [PATCH 075/114] More robust empty message for connectors --- src/application/pages/connectors/index.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/application/pages/connectors/index.tsx b/src/application/pages/connectors/index.tsx index 5cc0be518..7be155245 100644 --- a/src/application/pages/connectors/index.tsx +++ b/src/application/pages/connectors/index.tsx @@ -13,10 +13,19 @@ export function Route() { return ( -

    - All requests -

    - + + Queries and mutations that include connectors requests will show up + here. See the{" "} + + Apollo connectors docs + {" "} + for more information on using connectors. +
    ); } From 688d30be75bfbe941f4672a973e7427d534e711d Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Mon, 21 Oct 2024 17:11:41 -0600 Subject: [PATCH 076/114] Add alignment to tooltips --- src/application/components/Tooltip/Tooltip.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/application/components/Tooltip/Tooltip.tsx b/src/application/components/Tooltip/Tooltip.tsx index b516fb37b..f997569f4 100644 --- a/src/application/components/Tooltip/Tooltip.tsx +++ b/src/application/components/Tooltip/Tooltip.tsx @@ -3,6 +3,7 @@ import type { ReactNode } from "react"; interface TooltipProps { asChild?: boolean; + align?: "start" | "center" | "end"; content: ReactNode; children?: ReactNode; delayDuration?: number; @@ -11,6 +12,7 @@ interface TooltipProps { } export function Tooltip({ + align, content, children, delayDuration, @@ -25,6 +27,7 @@ export function Tooltip({ {children} Date: Mon, 21 Oct 2024 17:14:45 -0600 Subject: [PATCH 077/114] Add left border to query layout --- src/application/components/QueryLayout/Tabs.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application/components/QueryLayout/Tabs.tsx b/src/application/components/QueryLayout/Tabs.tsx index c2f7a823a..c79727978 100644 --- a/src/application/components/QueryLayout/Tabs.tsx +++ b/src/application/components/QueryLayout/Tabs.tsx @@ -16,7 +16,7 @@ export function Tabs({ }: TabsProps) { return ( Date: Mon, 21 Oct 2024 17:14:58 -0600 Subject: [PATCH 078/114] Don't show copy button for connectors tab --- src/application/components/Queries/Queries.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/application/components/Queries/Queries.tsx b/src/application/components/Queries/Queries.tsx index 31e459f15..62ee6fbb8 100644 --- a/src/application/components/Queries/Queries.tsx +++ b/src/application/components/Queries/Queries.tsx @@ -255,11 +255,13 @@ export const Queries = ({ clientId, explorerIFrame }: QueriesProps) => { Connectors - + {currentTab !== QueryTabs.Connectors && ( + + )} Date: Mon, 21 Oct 2024 17:25:32 -0600 Subject: [PATCH 079/114] Use the URL to navigate tabs --- src/application/App.tsx | 53 +++++++------------ .../components/Layouts/Navigation.tsx | 11 ---- .../Queries/RunInExplorerButton.tsx | 6 ++- src/application/router.tsx | 7 ++- 4 files changed, 29 insertions(+), 48 deletions(-) delete mode 100644 src/application/components/Layouts/Navigation.tsx diff --git a/src/application/App.tsx b/src/application/App.tsx index 91911c12e..e644a8353 100644 --- a/src/application/App.tsx +++ b/src/application/App.tsx @@ -1,11 +1,10 @@ import { Suspense, useEffect, useState } from "react"; import type { ReactNode } from "react"; import type { TypedDocumentNode } from "@apollo/client"; -import { useReactiveVar, gql, useQuery } from "@apollo/client"; +import { gql, useQuery } from "@apollo/client"; import { useMachine } from "@xstate/react"; import { ErrorBoundary } from "react-error-boundary"; -import { currentScreen, Screens } from "./components/Layouts/Navigation"; import { Queries } from "./components/Queries/Queries"; import { Mutations } from "./components/Mutations/Mutations"; import { Explorer } from "./components/Explorer/Explorer"; @@ -41,7 +40,7 @@ import { useActorEvent } from "./hooks/useActorEvent"; import { removeClient } from "."; import { PageError } from "./components/PageError"; import { SidebarLayout } from "./components/Layouts/SidebarLayout"; -import { Outlet, useNavigate } from "react-router-dom"; +import { Outlet, useMatches, useNavigate } from "react-router-dom"; import { PageSpinner } from "./components/PageSpinner"; const APP_QUERY: TypedDocumentNode = gql` @@ -118,11 +117,11 @@ export const App = () => { }); const navigate = useNavigate(); + const matches = useMatches(); const [settingsOpen, setSettingsOpen] = useState(false); const [selectedClientId, setSelectedClientId] = useState( data?.clients[0]?.id ); - const selected = useReactiveVar(currentScreen); const [embeddedExplorerIFrame, setEmbeddedExplorerIFrame] = useState(null); @@ -156,6 +155,9 @@ export const App = () => { } }, [send, clients.length]); + // The 0 index is always the root route and the selected tab is index 1. + const tab = matches[1]; + return ( <> @@ -166,16 +168,8 @@ export const App = () => { /> { - currentScreen(screen); - - if (screen === Screens.Connectors) { - navigate("/connectors"); - } else { - navigate("/"); - } - }} + value={tab?.pathname ?? "/queries"} + onChange={navigate} className="flex flex-col h-screen bg-primary dark:bg-primary-dark" >
    @@ -196,15 +190,15 @@ export const App = () => { - + Queries ({client?.queries.total ?? 0}) - + Mutations ({client?.mutations.total ?? 0}) - Cache - Connectors - Explorer + Cache + Connectors + Explorer
    {client?.version && ( @@ -272,22 +266,19 @@ export const App = () => { */} - + { /> - + { /> - + }> - + diff --git a/src/application/components/Layouts/Navigation.tsx b/src/application/components/Layouts/Navigation.tsx deleted file mode 100644 index be5bc4289..000000000 --- a/src/application/components/Layouts/Navigation.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { makeVar } from "@apollo/client"; - -export enum Screens { - Cache = "cache", - Queries = "queries", - Mutations = "mutations", - Connectors = "connectors", - Explorer = "explorer", -} - -export const currentScreen = makeVar(Screens.Queries); diff --git a/src/application/components/Queries/RunInExplorerButton.tsx b/src/application/components/Queries/RunInExplorerButton.tsx index bf7a98338..79a62358e 100644 --- a/src/application/components/Queries/RunInExplorerButton.tsx +++ b/src/application/components/Queries/RunInExplorerButton.tsx @@ -3,9 +3,9 @@ import { postMessageToEmbed, SET_OPERATION, } from "../Explorer/postMessageHelpers"; -import { currentScreen, Screens } from "../Layouts/Navigation"; import IconRun from "@apollo/icons/default/IconRun.svg"; import { Button } from "../Button"; +import { useNavigate } from "react-router-dom"; interface RunInExplorerButtonProps { operation: string; @@ -18,6 +18,8 @@ export const RunInExplorerButton = ({ variables, embeddedExplorerIFrame, }: RunInExplorerButtonProps): JSX.Element | null => { + const navigate = useNavigate(); + return (