Skip to content

Commit

Permalink
docs: improve API testing feature (#7311)
Browse files Browse the repository at this point in the history
  • Loading branch information
shahednasser authored May 14, 2024
1 parent 5b26f5f commit 70c4fff
Show file tree
Hide file tree
Showing 10 changed files with 368 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"use client"

import React, { useEffect, useState } from "react"
import { ApiRunnerParamInput, ApiRunnerParamInputProps } from "../Default"
import clsx from "clsx"
import setObjValue from "@/utils/set-obj-value"
import { Button } from "../../../.."
import { Minus, Plus } from "@medusajs/icons"

export const ApiRunnerParamArrayInput = ({
paramName,
paramValue,
objPath,
setValue,
}: ApiRunnerParamInputProps) => {
const [itemsValue, setItemsValue] = useState<typeof paramValue>(paramValue)

useEffect(() => {
setValue((prev: unknown) => {
return typeof prev === "object"
? setObjValue({
obj: { ...prev },
value: itemsValue,
path: `${objPath.length ? `${objPath}.` : ""}${paramName}`,
})
: itemsValue
})
}, [itemsValue])

if (!Array.isArray(paramValue)) {
return (
<ApiRunnerParamInput
paramName={paramName}
paramValue={paramValue}
objPath={objPath}
setValue={setValue}
/>
)
}

return (
<fieldset
className={clsx(
"border border-medusa-border-strong rounded",
"p-docs_0.5"
)}
>
<legend className="px-docs_0.5">
<code>{paramName}</code> Array Items
</legend>
{(itemsValue as unknown[]).map((value, index) => (
<div
key={index}
className={clsx(
index > 0 &&
"flex gap-docs_0.5 items-center justify-center mt-docs_0.5"
)}
>
<ApiRunnerParamInput
paramName={`[${index}]`}
paramValue={value}
objPath={""}
setValue={setItemsValue}
/>
{index > 0 && (
<Button
buttonType="icon"
variant="secondary"
onClick={() => {
setItemsValue((prev: unknown[]) => prev.splice(index, 1))
}}
className="mt-0.5"
>
<Minus />
</Button>
)}
</div>
))}
<Button
buttonType="icon"
variant="secondary"
onClick={() => {
setItemsValue((prev: unknown[]) => [
...prev,
Array.isArray(prev[0])
? [...prev[0]]
: typeof prev[0] === "object"
? Object.assign({}, prev[0])
: prev[0],
])
}}
className="mt-0.5"
>
<Plus />
</Button>
</fieldset>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React from "react"
import { InputText } from "../../../.."
import setObjValue from "../../../../utils/set-obj-value"
import { ApiRunnerParamObjectInput } from "../Object"
import { ApiRunnerParamArrayInput } from "../Array"

export type ApiRunnerParamInputProps = {
paramName: string
paramValue: unknown
objPath: string
setValue: React.Dispatch<React.SetStateAction<unknown>>
}

export const ApiRunnerParamInput = ({
paramName,
paramValue,
objPath,
setValue,
}: ApiRunnerParamInputProps) => {
if (Array.isArray(paramValue)) {
return (
<ApiRunnerParamArrayInput
paramName={paramName}
paramValue={paramValue}
objPath={objPath}
setValue={setValue}
/>
)
}
if (typeof paramValue === "object") {
return (
<ApiRunnerParamObjectInput
paramName={paramName}
paramValue={paramValue}
objPath={objPath}
setValue={setValue}
/>
)
}

return (
<InputText
name={paramName}
onChange={(e) => {
setValue((prev: unknown) => {
if (Array.isArray(prev)) {
// try to get index from param name
const splitPath = objPath.split(".")
// if param is in an object in the array, the index is
// the last item of the `objPath`. Otherwise, it's in the param name
const index = (
objPath.length > 0 ? splitPath[splitPath.length - 1] : paramName
)
.replace("[", "")
.replace("]", "")
const intIndex = parseInt(index)

// if we can't get the index from the param name or obj path
// just insert the value to the end of the array.
if (Number.isNaN(intIndex)) {
return [...prev, e.target.value]
}

// if the param is within an object, the value to be set
// is the updated value of the object. Otherwise, it's just the
// value of the item.
const transformedValue =
prev.length > 0 && typeof prev[0] === "object"
? setObjValue({
obj: { ...prev[intIndex] },
value: e.target.value,
path: paramName,
})
: e.target.value

return [
...prev.slice(0, intIndex),
transformedValue,
...prev.slice(intIndex + 1),
]
}

return typeof prev === "object"
? setObjValue({
obj: { ...prev },
value: e.target.value,
path: `${objPath.length ? `${objPath}.` : ""}${paramName}`,
})
: e.target.value
})
}}
placeholder={paramName}
value={
typeof paramValue === "string"
? (paramValue as string)
: typeof paramValue === "number"
? (paramValue as number)
: `${paramValue}`
}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from "react"
import { ApiRunnerParamInput, ApiRunnerParamInputProps } from "../Default"
import clsx from "clsx"

export const ApiRunnerParamObjectInput = ({
paramName,
paramValue,
objPath,
...props
}: ApiRunnerParamInputProps) => {
if (typeof paramValue !== "object") {
return (
<ApiRunnerParamInput
paramName={paramName}
paramValue={paramValue}
objPath={objPath}
{...props}
/>
)
}

return (
<fieldset
className={clsx(
"border border-medusa-border-strong rounded",
"p-docs_0.5"
)}
>
<legend className="px-docs_0.5">
<code>{paramName}</code> Properties
</legend>
{Object.entries(paramValue as Record<string, unknown>).map(
([key, value], index) => (
<ApiRunnerParamInput
paramName={key}
paramValue={value}
objPath={`${objPath.length ? `${objPath}.` : ""}${paramName}`}
key={index}
{...props}
/>
)
)}
</fieldset>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from "react"
import { ApiRunnerParamInput } from "./Default"

export type ApiRunnerParamInputsProps = {
data: Record<string, unknown>
title: string
baseObjPath: string
setValue: React.Dispatch<React.SetStateAction<unknown>>
}

export const ApiRunnerParamInputs = ({
data,
title,
baseObjPath,
setValue,
}: ApiRunnerParamInputsProps) => {
return (
<div className="flex flex-col gap-docs_0.5">
<span className="text-compact-medium-plus text-medusa-fg-base">
{title}
</span>
<div className="flex gap-docs_0.5">
{Object.keys(data).map((pathParam, index) => (
<ApiRunnerParamInput
paramName={pathParam}
paramValue={data[pathParam]}
objPath={baseObjPath}
setValue={setValue}
key={index}
/>
))}
</div>
</div>
)
}
Loading

0 comments on commit 70c4fff

Please sign in to comment.