fix: enhance dropdown component with refresh button and clean up parameter render logic (#8493)
* fix: enhance dropdown component with refresh button and clean up parameter render logic - Added a refresh button to the dropdown component, improving user interaction. - Refactored parameter render component to remove unnecessary wrapping around the render function. - Updated package-lock.json to remove extraneous dependencies. * [autofix.ci] apply automated fixes * refactor(OutputComponent): replace DropdownMenu with Popover and Command components - Updated OutputComponent to use Popover and Command components for improved UI interaction. - Refactored dropdown logic to enhance accessibility and user experience. - Added a reference for the button to manage focus visibility. * refactor: update Memory Chatbot configuration and remove unused RefreshParameterComponent - Changed display names and output methods in Memory Chatbot JSON configuration for clarity and consistency. - Introduced a new output method for retrieving messages as text. - Removed the RefreshParameterComponent and its references from the parameter render component to streamline the codebase. * refactor: update dropdown component layout for improved styling - Changed the layout classes in the dropdown component to enhance responsiveness and visual consistency. - Adjusted flex properties to ensure proper alignment and spacing based on the presence of filtered metadata. * refactor: streamline dropdown component structure and enhance button functionality - Removed redundant rendering functions for refresh and custom option dialogs, integrating them directly into the dropdown's main structure. - Improved layout and styling for better responsiveness and visual consistency. - Adjusted class names for better alignment and spacing, particularly in relation to filtered metadata. - Ensured the refresh button is consistently displayed based on dialog input conditions. * refactor: enhance dropdown component styling for better readability - Updated text size in dropdown options for improved visibility. - Increased padding in command items for better touch targets and visual consistency. * refactor: adjust dropdown component styling for improved usability - Reduced padding in the search input for a more compact design. - Updated text size in the search input for better readability. - Enhanced layout of filtered metadata display for clearer visibility. * refactor: enhance dropdown component rendering and styling - Added console log for filtered metadata to assist in debugging. - Adjusted class names in dropdown options for better responsiveness based on filtered metadata length. * feat: add data-testid attributes for refresh buttons and simplify memoization in ParameterRenderComponent - Added data-testid attributes to refresh buttons in Dropdown component for improved testability. - Removed unnecessary useMemo in ParameterRenderComponent to streamline rendering logic. - Introduced a new test for the refresh dropdown list functionality to ensure proper behavior. --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
5734735e2d
commit
466a18c744
5 changed files with 204 additions and 202 deletions
|
|
@ -1,12 +1,19 @@
|
||||||
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
|
import { ForwardedIconComponent } from "@/components/common/genericIconComponent";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
Command,
|
||||||
DropdownMenuContent,
|
CommandGroup,
|
||||||
DropdownMenuItem,
|
CommandItem,
|
||||||
DropdownMenuTrigger,
|
CommandList,
|
||||||
} from "@/components/ui/dropdown-menu";
|
} from "@/components/ui/command";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContentWithoutPortal,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
import useFlowStore from "@/stores/flowStore";
|
import useFlowStore from "@/stores/flowStore";
|
||||||
|
import { useRef } from "react";
|
||||||
import ShadTooltip from "../../../../components/common/shadTooltipComponent";
|
import ShadTooltip from "../../../../components/common/shadTooltipComponent";
|
||||||
import { outputComponentType } from "../../../../types/components";
|
import { outputComponentType } from "../../../../types/components";
|
||||||
import { cn } from "../../../../utils/utils";
|
import { cn } from "../../../../utils/utils";
|
||||||
|
|
@ -56,6 +63,7 @@ export default function OutputComponent({
|
||||||
const hasGroupOutputs = outputs?.some?.((output) => output.group_outputs);
|
const hasGroupOutputs = outputs?.some?.((output) => output.group_outputs);
|
||||||
const isConditionalRouter = nodeType === "ConditionalRouter";
|
const isConditionalRouter = nodeType === "ConditionalRouter";
|
||||||
const hasOutputs = outputs.length > 1;
|
const hasOutputs = outputs.length > 1;
|
||||||
|
const refButton = useRef<HTMLButtonElement>(null);
|
||||||
|
|
||||||
const shouldShowDropdown =
|
const shouldShowDropdown =
|
||||||
hasOutputs && !hasLoopOutput && !hasGroupOutputs && !isConditionalRouter;
|
hasOutputs && !hasLoopOutput && !hasGroupOutputs && !isConditionalRouter;
|
||||||
|
|
@ -63,11 +71,13 @@ export default function OutputComponent({
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{shouldShowDropdown ? (
|
{shouldShowDropdown ? (
|
||||||
<DropdownMenu>
|
<Popover>
|
||||||
<DropdownMenuTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
unstyled
|
unstyled
|
||||||
className="group flex items-center gap-2"
|
role="combobox"
|
||||||
|
ref={refButton}
|
||||||
|
className="no-focus-visible group flex items-center gap-2"
|
||||||
data-testid={`dropdown-output-${outputName?.toLowerCase()}`}
|
data-testid={`dropdown-output-${outputName?.toLowerCase()}`}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-1 truncate rounded-md px-2 py-1 text-[13px] font-medium group-hover:bg-primary/10">
|
<div className="flex items-center gap-1 truncate rounded-md px-2 py-1 text-[13px] font-medium group-hover:bg-primary/10">
|
||||||
|
|
@ -78,16 +88,24 @@ export default function OutputComponent({
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</PopoverTrigger>
|
||||||
<DropdownMenuContent className="min-w-[200px] max-w-[250px]">
|
<PopoverContentWithoutPortal
|
||||||
|
side="bottom"
|
||||||
|
align="end"
|
||||||
|
className="noflow nowheel nopan nodelete nodrag w-full min-w-[200px] max-w-[250px] p-0"
|
||||||
|
>
|
||||||
|
<Command>
|
||||||
|
<CommandList>
|
||||||
|
<CommandGroup defaultChecked={false} className="p-0">
|
||||||
{outputs.map((output) => (
|
{outputs.map((output) => (
|
||||||
<DropdownMenuItem
|
<CommandItem
|
||||||
key={output.name}
|
key={output.name}
|
||||||
data-testid={`dropdown-item-output-${outputName?.toLowerCase()}-${output.display_name?.toLowerCase()}`}
|
data-testid={`dropdown-item-output-${outputName?.toLowerCase()}-${output.display_name?.toLowerCase()}`}
|
||||||
className="cursor-pointer justify-between px-3 py-2"
|
className="cursor-pointer justify-between rounded-none px-3 py-2"
|
||||||
onClick={() => {
|
onSelect={() => {
|
||||||
handleSelectOutput && handleSelectOutput(output);
|
handleSelectOutput && handleSelectOutput(output);
|
||||||
}}
|
}}
|
||||||
|
value={output.name}
|
||||||
>
|
>
|
||||||
<span className="truncate text-[13px]">
|
<span className="truncate text-[13px]">
|
||||||
{output.display_name ?? output.name}
|
{output.display_name ?? output.name}
|
||||||
|
|
@ -95,10 +113,13 @@ export default function OutputComponent({
|
||||||
<span className="ml-4 text-[13px] text-muted-foreground">
|
<span className="ml-4 text-[13px] text-muted-foreground">
|
||||||
{output.types.join(", ")}
|
{output.types.join(", ")}
|
||||||
</span>
|
</span>
|
||||||
</DropdownMenuItem>
|
</CommandItem>
|
||||||
))}
|
))}
|
||||||
</DropdownMenuContent>
|
</CommandGroup>
|
||||||
</DropdownMenu>
|
</CommandList>
|
||||||
|
</Command>
|
||||||
|
</PopoverContentWithoutPortal>
|
||||||
|
</Popover>
|
||||||
) : (
|
) : (
|
||||||
singleOutput
|
singleOutput
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ export default function Dropdown({
|
||||||
const fuse = new Fuse(validOptions, { keys: ["name", "value"] });
|
const fuse = new Fuse(validOptions, { keys: ["name", "value"] });
|
||||||
const PopoverContentDropdown =
|
const PopoverContentDropdown =
|
||||||
children || editNode ? PopoverContent : PopoverContentWithoutPortal;
|
children || editNode ? PopoverContent : PopoverContentWithoutPortal;
|
||||||
const { helperText } = baseInputProps;
|
const { helperText, hasRefreshButton } = baseInputProps;
|
||||||
|
|
||||||
// API and store hooks
|
// API and store hooks
|
||||||
const postTemplateValue = usePostTemplateValue({
|
const postTemplateValue = usePostTemplateValue({
|
||||||
|
|
@ -357,7 +357,7 @@ export default function Dropdown({
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderSearchInput = () => (
|
const renderSearchInput = () => (
|
||||||
<div className="flex items-center border-b px-3">
|
<div className="flex items-center border-b px-2.5">
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
name="search"
|
name="search"
|
||||||
className="mr-2 h-4 w-4 shrink-0 opacity-50"
|
className="mr-2 h-4 w-4 shrink-0 opacity-50"
|
||||||
|
|
@ -366,16 +366,127 @@ export default function Dropdown({
|
||||||
onChange={searchRoleByTerm}
|
onChange={searchRoleByTerm}
|
||||||
onKeyDown={handleInputKeyDown}
|
onKeyDown={handleInputKeyDown}
|
||||||
placeholder="Search options..."
|
placeholder="Search options..."
|
||||||
className="flex h-9 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
className="flex h-9 w-full rounded-md bg-transparent py-3 text-[13px] outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
data-testid="dropdown_search_input"
|
data-testid="dropdown_search_input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const renderCustomOptionDialog = () => (
|
const renderOptionsList = () => (
|
||||||
<CommandGroup className="flex flex-col">
|
<CommandList className="max-h-[300px] overflow-y-auto">
|
||||||
<CommandItem className="flex cursor-pointer items-center justify-start gap-2 truncate py-3 text-xs font-semibold text-muted-foreground">
|
<CommandGroup defaultChecked={false} className="p-0">
|
||||||
|
{filteredOptions?.length > 0 ? (
|
||||||
|
filteredOptions?.map((option, index) => (
|
||||||
|
<ShadTooltip
|
||||||
|
key={index}
|
||||||
|
delayDuration={700}
|
||||||
|
styleClasses="whitespace-pre-wrap"
|
||||||
|
content={formatTooltipContent(option, index)}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<CommandItem
|
||||||
|
value={option}
|
||||||
|
onSelect={(currentValue) => {
|
||||||
|
onSelect(currentValue);
|
||||||
|
setOpen(false);
|
||||||
|
}}
|
||||||
|
className="w-full items-center rounded-none"
|
||||||
|
data-testid={`${option}-${index}-option`}
|
||||||
|
>
|
||||||
|
<div className="flex w-full items-center gap-2">
|
||||||
|
{filteredMetadata?.[index]?.icon && (
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name={filteredMetadata?.[index]?.icon || "Unknown"}
|
||||||
|
className="h-4 w-4 shrink-0 text-primary"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={cn("flex w-full", {
|
||||||
|
"pl-2": !filteredMetadata?.[index]?.icon,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={cn("truncate text-[13px]", {
|
||||||
|
"w-1/2": filteredMetadata?.length !== 0,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{option}
|
||||||
|
</div>
|
||||||
|
{filteredMetadata?.[index]?.status && (
|
||||||
|
<span
|
||||||
|
className={`flex items-center pl-2 text-xs ${getStatusColor(
|
||||||
|
filteredMetadata?.[index]?.status,
|
||||||
|
)}`}
|
||||||
|
>
|
||||||
|
<LoadingTextComponent
|
||||||
|
text={filteredMetadata?.[
|
||||||
|
index
|
||||||
|
]?.status?.toLowerCase()}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{filteredMetadata && filteredMetadata?.length > 0 && (
|
||||||
|
<div className="ml-auto flex items-center overflow-hidden pl-2 text-muted-foreground">
|
||||||
|
{Object.entries(
|
||||||
|
filterMetadataKeys(filteredMetadata?.[index] || {}),
|
||||||
|
)
|
||||||
|
.filter(
|
||||||
|
([key, value]) =>
|
||||||
|
value !== null && key !== "icon",
|
||||||
|
)
|
||||||
|
.map(([key, value], i, arr) => (
|
||||||
|
<div
|
||||||
|
key={key}
|
||||||
|
className={cn("flex items-center", {
|
||||||
|
"flex-1 overflow-hidden":
|
||||||
|
i === arr.length - 1,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{i > 0 && (
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name="Circle"
|
||||||
|
className="mx-1 h-1 w-1 flex-shrink-0 overflow-visible fill-muted-foreground"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="truncate text-xs">
|
||||||
|
{`${String(value)} ${key}`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className={cn("pl-2", {
|
||||||
|
"ml-auto":
|
||||||
|
!filteredMetadata || filteredMetadata.length === 0,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name="Check"
|
||||||
|
className={cn(
|
||||||
|
"h-4 w-4 shrink-0 text-primary",
|
||||||
|
value === option ? "opacity-100" : "opacity-0",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CommandItem>
|
||||||
|
</div>
|
||||||
|
</ShadTooltip>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<CommandItem disabled className="text-center text-sm">
|
||||||
|
No options found
|
||||||
|
</CommandItem>
|
||||||
|
)}
|
||||||
|
</CommandGroup>
|
||||||
|
<CommandSeparator />
|
||||||
|
{dialogInputs && dialogInputs?.fields && (
|
||||||
|
<CommandGroup className="p-0">
|
||||||
|
<CommandItem className="flex cursor-pointer items-center justify-start gap-2 truncate rounded-none py-2.5 text-xs font-semibold text-muted-foreground">
|
||||||
<Button
|
<Button
|
||||||
className="w-full"
|
className="w-full"
|
||||||
unstyled
|
unstyled
|
||||||
|
|
@ -392,10 +503,11 @@ export default function Dropdown({
|
||||||
</div>
|
</div>
|
||||||
</Button>
|
</Button>
|
||||||
</CommandItem>
|
</CommandItem>
|
||||||
<CommandItem className="flex cursor-pointer items-center justify-start gap-2 truncate py-3 text-xs font-semibold text-muted-foreground">
|
<CommandItem className="flex cursor-pointer items-center justify-start gap-2 truncate rounded-none py-2.5 text-xs font-semibold text-muted-foreground">
|
||||||
<Button
|
<Button
|
||||||
className="w-full"
|
className="w-full"
|
||||||
unstyled
|
unstyled
|
||||||
|
data-testid={`refresh-dropdown-list-${name}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleRefreshButtonPress();
|
handleRefreshButtonPress();
|
||||||
}}
|
}}
|
||||||
|
|
@ -421,113 +533,7 @@ export default function Dropdown({
|
||||||
nodeClass={nodeClass!}
|
nodeClass={nodeClass!}
|
||||||
/>
|
/>
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
);
|
|
||||||
|
|
||||||
const renderOptionsList = () => (
|
|
||||||
<CommandList>
|
|
||||||
<CommandGroup defaultChecked={false}>
|
|
||||||
{filteredOptions?.length > 0 ? (
|
|
||||||
filteredOptions?.map((option, index) => (
|
|
||||||
<ShadTooltip
|
|
||||||
key={index}
|
|
||||||
delayDuration={700}
|
|
||||||
styleClasses="whitespace-pre-wrap"
|
|
||||||
content={formatTooltipContent(option, index)}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<CommandItem
|
|
||||||
value={option}
|
|
||||||
onSelect={(currentValue) => {
|
|
||||||
onSelect(currentValue);
|
|
||||||
setOpen(false);
|
|
||||||
}}
|
|
||||||
className="items-center"
|
|
||||||
data-testid={`${option}-${index}-option`}
|
|
||||||
>
|
|
||||||
<div className="flex w-full items-center gap-2">
|
|
||||||
{filteredMetadata?.[index]?.icon && (
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name={filteredMetadata?.[index]?.icon || "Unknown"}
|
|
||||||
className="h-4 w-4 shrink-0 text-primary"
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<div
|
|
||||||
className={cn("flex truncate", {
|
|
||||||
"flex-col":
|
|
||||||
filteredMetadata && filteredMetadata?.length > 0,
|
|
||||||
"w-full pl-2": !filteredMetadata?.[index]?.icon,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<div className="flex truncate">
|
|
||||||
{option}{" "}
|
|
||||||
<span
|
|
||||||
className={`flex items-center pl-2 text-xs ${getStatusColor(
|
|
||||||
filteredMetadata?.[index]?.status,
|
|
||||||
)}`}
|
|
||||||
>
|
|
||||||
<LoadingTextComponent
|
|
||||||
text={filteredMetadata?.[
|
|
||||||
index
|
|
||||||
]?.status?.toLowerCase()}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{filteredMetadata && filteredMetadata?.length > 0 ? (
|
|
||||||
<div className="flex w-full items-center overflow-hidden text-muted-foreground">
|
|
||||||
{Object.entries(
|
|
||||||
filterMetadataKeys(filteredMetadata?.[index] || {}),
|
|
||||||
)
|
|
||||||
.filter(
|
|
||||||
([key, value]) =>
|
|
||||||
value !== null && key !== "icon",
|
|
||||||
)
|
|
||||||
.map(([key, value], i, arr) => (
|
|
||||||
<div
|
|
||||||
key={key}
|
|
||||||
className={cn("flex items-center", {
|
|
||||||
"flex-1 overflow-hidden":
|
|
||||||
i === arr.length - 1,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{i > 0 && (
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name="Circle"
|
|
||||||
className="mx-1 h-1 w-1 flex-shrink-0 overflow-visible fill-muted-foreground"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div
|
|
||||||
className={cn("text-xs", {
|
|
||||||
"w-full truncate": i === arr.length - 1,
|
|
||||||
})}
|
|
||||||
>{`${String(value)} ${key}`}</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="ml-auto flex">
|
|
||||||
<ForwardedIconComponent
|
|
||||||
name="Check"
|
|
||||||
className={cn(
|
|
||||||
"h-4 w-4 shrink-0 text-primary",
|
|
||||||
value === option ? "opacity-100" : "opacity-0",
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</CommandItem>
|
|
||||||
</div>
|
|
||||||
</ShadTooltip>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<CommandItem disabled className="text-center text-sm">
|
|
||||||
No options found
|
|
||||||
</CommandItem>
|
|
||||||
)}
|
|
||||||
</CommandGroup>
|
|
||||||
<CommandSeparator />
|
|
||||||
{dialogInputs && dialogInputs?.fields && renderCustomOptionDialog()}
|
|
||||||
</CommandList>
|
</CommandList>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -540,9 +546,31 @@ export default function Dropdown({
|
||||||
children ? {} : { minWidth: refButton?.current?.clientWidth ?? "200px" }
|
children ? {} : { minWidth: refButton?.current?.clientWidth ?? "200px" }
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Command>
|
<Command className="flex flex-col">
|
||||||
{options?.length > 0 && renderSearchInput()}
|
{options?.length > 0 && renderSearchInput()}
|
||||||
{renderOptionsList()}
|
{renderOptionsList()}
|
||||||
|
{!dialogInputs?.fields && hasRefreshButton && (
|
||||||
|
<div className="sticky bottom-0 border-t bg-background">
|
||||||
|
<CommandItem className="flex cursor-pointer items-center justify-start gap-2 truncate rounded-b-md py-3 text-xs font-semibold text-muted-foreground">
|
||||||
|
<Button
|
||||||
|
className="w-full"
|
||||||
|
unstyled
|
||||||
|
data-testid={`refresh-dropdown-list-${name}`}
|
||||||
|
onClick={() => {
|
||||||
|
handleRefreshButtonPress();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-2 pl-1">
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name="RefreshCcw"
|
||||||
|
className={cn("refresh-icon h-3 w-3 text-primary")}
|
||||||
|
/>
|
||||||
|
Refresh list
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</CommandItem>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Command>
|
</Command>
|
||||||
</PopoverContentDropdown>
|
</PopoverContentDropdown>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
import { RefreshButton } from "@/components/ui/refreshButton";
|
|
||||||
import { FLEX_VIEW_TYPES } from "@/constants/constants";
|
|
||||||
import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value";
|
|
||||||
import { mutateTemplate } from "@/CustomNodes/helpers/mutate-template";
|
|
||||||
import useAlertStore from "@/stores/alertStore";
|
|
||||||
import { APIClassType, InputFieldType } from "@/types/api";
|
|
||||||
import { cn } from "@/utils/utils";
|
|
||||||
import { InputProps } from "../../types";
|
|
||||||
|
|
||||||
export function RefreshParameterComponent({
|
|
||||||
children,
|
|
||||||
templateData,
|
|
||||||
disabled,
|
|
||||||
nodeClass,
|
|
||||||
editNode,
|
|
||||||
handleNodeClass,
|
|
||||||
nodeId,
|
|
||||||
name,
|
|
||||||
}: {
|
|
||||||
children: React.ReactElement<InputProps>;
|
|
||||||
templateData: Partial<InputFieldType>;
|
|
||||||
disabled: boolean;
|
|
||||||
nodeClass: APIClassType;
|
|
||||||
editNode: boolean;
|
|
||||||
handleNodeClass: (value: any, code?: string, type?: string) => void;
|
|
||||||
nodeId: string;
|
|
||||||
name: string;
|
|
||||||
}) {
|
|
||||||
const postTemplateValue = usePostTemplateValue({
|
|
||||||
parameterId: name,
|
|
||||||
nodeId: nodeId,
|
|
||||||
node: nodeClass,
|
|
||||||
});
|
|
||||||
|
|
||||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
|
||||||
const handleRefreshButtonPress = () =>
|
|
||||||
mutateTemplate(
|
|
||||||
templateData.value,
|
|
||||||
nodeId,
|
|
||||||
nodeClass,
|
|
||||||
handleNodeClass,
|
|
||||||
postTemplateValue,
|
|
||||||
setErrorData,
|
|
||||||
);
|
|
||||||
|
|
||||||
const isFlexView = FLEX_VIEW_TYPES.includes(templateData.type ?? "");
|
|
||||||
|
|
||||||
return (
|
|
||||||
(children ||
|
|
||||||
(templateData.refresh_button && !templateData.dialog_inputs)) && (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"flex w-full items-center justify-center gap-3",
|
|
||||||
isFlexView ? "justify-end" : "justify-center",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
{templateData.refresh_button &&
|
|
||||||
!templateData.dialog_inputs?.fields?.data?.node?.template && (
|
|
||||||
<div className="shrink-0 flex-col">
|
|
||||||
<RefreshButton
|
|
||||||
isLoading={postTemplateValue.isPending}
|
|
||||||
disabled={disabled}
|
|
||||||
editNode={editNode}
|
|
||||||
button_text={templateData.refresh_button_text}
|
|
||||||
handleUpdateValues={handleRefreshButtonPress}
|
|
||||||
id={"refresh-button-" + name}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -20,7 +20,6 @@ import McpComponent from "./components/mcpComponent";
|
||||||
import MultiselectComponent from "./components/multiselectComponent";
|
import MultiselectComponent from "./components/multiselectComponent";
|
||||||
import PromptAreaComponent from "./components/promptComponent";
|
import PromptAreaComponent from "./components/promptComponent";
|
||||||
import QueryComponent from "./components/queryComponent";
|
import QueryComponent from "./components/queryComponent";
|
||||||
import { RefreshParameterComponent } from "./components/refreshParameterComponent";
|
|
||||||
import SortableListComponent from "./components/sortableListComponent";
|
import SortableListComponent from "./components/sortableListComponent";
|
||||||
import { StrRenderComponent } from "./components/strRenderComponent";
|
import { StrRenderComponent } from "./components/strRenderComponent";
|
||||||
import ToggleShadComponent from "./components/toggleShadComponent";
|
import ToggleShadComponent from "./components/toggleShadComponent";
|
||||||
|
|
@ -295,20 +294,5 @@ export function ParameterRenderComponent({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return useMemo(
|
return renderComponent();
|
||||||
() => (
|
|
||||||
<RefreshParameterComponent
|
|
||||||
templateData={templateData}
|
|
||||||
disabled={disabled}
|
|
||||||
nodeId={nodeId}
|
|
||||||
editNode={editNode}
|
|
||||||
nodeClass={nodeClass}
|
|
||||||
handleNodeClass={handleNodeClass}
|
|
||||||
name={name}
|
|
||||||
>
|
|
||||||
{renderComponent()}
|
|
||||||
</RefreshParameterComponent>
|
|
||||||
),
|
|
||||||
[templateData, disabled, nodeId, editNode, nodeClass, name, templateValue],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { test } from "@playwright/test";
|
||||||
|
import * as dotenv from "dotenv";
|
||||||
|
import path from "path";
|
||||||
|
import { awaitBootstrapTest } from "../../utils/await-bootstrap-test";
|
||||||
|
import { initialGPTsetup } from "../../utils/initialGPTsetup";
|
||||||
|
|
||||||
|
test(
|
||||||
|
"refresh dropdown list",
|
||||||
|
{ tag: ["@release", "@components"] },
|
||||||
|
async ({ page }) => {
|
||||||
|
test.skip(
|
||||||
|
!process?.env?.ANTHROPIC_API_KEY,
|
||||||
|
"ANTHROPIC_API_KEY required to run this test",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!process.env.CI) {
|
||||||
|
dotenv.config({ path: path.resolve(__dirname, "../../.env") });
|
||||||
|
}
|
||||||
|
|
||||||
|
await page.goto("/");
|
||||||
|
await awaitBootstrapTest(page);
|
||||||
|
|
||||||
|
await page.getByTestId("side_nav_options_all-templates").click();
|
||||||
|
await page
|
||||||
|
.getByRole("heading", { name: "Portfolio Website Code Generator" })
|
||||||
|
.click();
|
||||||
|
|
||||||
|
await page.waitForSelector('[data-testid="fit_view"]', {
|
||||||
|
timeout: 100000,
|
||||||
|
});
|
||||||
|
|
||||||
|
await initialGPTsetup(page, {
|
||||||
|
skipAdjustScreenView: true,
|
||||||
|
skipSelectGptModel: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.waitForTimeout(3000);
|
||||||
|
|
||||||
|
await page.getByTestId("dropdown_str_model_name").first().click();
|
||||||
|
await page.getByTestId("refresh-dropdown-list-model_name").first().click();
|
||||||
|
await page.getByText("Loading Options").isVisible({ timeout: 5000 });
|
||||||
|
},
|
||||||
|
);
|
||||||
Loading…
Add table
Add a link
Reference in a new issue