fix: update Gmail icon to Google and improve ListSelectionComponent styles (#7591)
* fix: update Gmail icon to Google and improve ListSelectionComponent styles
* fix: remove unnecessary info and improve required field handling in Composio components
* style: update ListSelectionComponent and SortableListItem for improved layout and styling
* fix: enhance ListSelectionComponent and SortableListComponent to support search functionality
* style: adjust height and padding in SortableListItem for better visual consistency
* ✅ (intComponent.spec.ts): update test assertions to match expected behavior after changes in the component's functionality
---------
Co-authored-by: cristhianzl <cristhian.lousa@gmail.com>
This commit is contained in:
parent
ae2ef5d8e4
commit
28675d873f
11 changed files with 64 additions and 45 deletions
|
|
@ -38,7 +38,6 @@ class ComposioBaseComponent(Component):
|
|||
name="api_key",
|
||||
display_name="Composio API Key",
|
||||
required=True,
|
||||
info="Refer to https://docs.composio.dev/faq/api_key/api_key",
|
||||
real_time_refresh=True,
|
||||
value="COMPOSIO_API_KEY",
|
||||
),
|
||||
|
|
@ -53,12 +52,11 @@ class ComposioBaseComponent(Component):
|
|||
placeholder="Select action",
|
||||
options=[],
|
||||
value="disabled",
|
||||
info="Select action to pass to the agent",
|
||||
helper_text="Please connect before selecting actions.",
|
||||
helper_text_metadata={"variant": "destructive"},
|
||||
show=True,
|
||||
required=False,
|
||||
real_time_refresh=True,
|
||||
required=True,
|
||||
limit=1,
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -16,9 +16,8 @@ class ComposioGmailAPIComponent(ComposioBaseComponent):
|
|||
"""Gmail API component for interacting with Gmail services."""
|
||||
|
||||
display_name: str = "Gmail"
|
||||
description: str = "Gmail API"
|
||||
name = "GmailAPI"
|
||||
icon = "Gmail"
|
||||
icon = "Google"
|
||||
documentation: str = "https://docs.composio.dev"
|
||||
app_name = "gmail"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import ForwardedIconComponent from "@/components/common/genericIconComponent";
|
||||
import ShadTooltip from "@/components/common/shadTooltipComponent";
|
||||
import SearchBarComponent from "@/components/core/parameterRenderComponent/components/searchBarComponent";
|
||||
import { InputProps } from "@/components/core/parameterRenderComponent/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { DialogHeader } from "@/components/ui/dialog";
|
||||
import { Dialog, DialogContent } from "@/components/ui/dialog-with-no-close";
|
||||
import { cn, testIdCase } from "@/utils/utils";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
|
|
@ -64,8 +66,9 @@ const ListItem = ({
|
|||
unstyled
|
||||
size="sm"
|
||||
className={cn(
|
||||
"group w-full rounded-md py-3 pl-3 pr-3",
|
||||
"group flex w-full rounded-md px-2 py-0.5",
|
||||
!isKeyboardNavActive && "hover:bg-muted", // Only apply hover styles when not in keyboard nav
|
||||
!item.metaData && "py-2.5",
|
||||
isFocused && "bg-muted",
|
||||
className,
|
||||
)}
|
||||
|
|
@ -85,21 +88,30 @@ const ListItem = ({
|
|||
>
|
||||
<div className="flex w-full items-center gap-2">
|
||||
{item.icon && (
|
||||
<ForwardedIconComponent name={item.icon} className="h-5 w-5" />
|
||||
)}
|
||||
<div className="truncate text-sm">{item.name}</div>
|
||||
{"metaData" in item && item.metaData && (
|
||||
<div className="text-gray-500">{item.metaData}</div>
|
||||
<div>
|
||||
<ForwardedIconComponent name={item.icon} className="mr-2 h-4 w-4" />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex w-full flex-col truncate">
|
||||
<div className="flex w-full truncate text-[13px] font-semibold">
|
||||
<span className="truncate">{item.name}</span>
|
||||
</div>
|
||||
{"metaData" in item && item.metaData && (
|
||||
<div className="flex w-full truncate text-[13px] text-gray-500">
|
||||
<span className="truncate">{item.metaData}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isHovered || isFocused ? (
|
||||
<div className="ml-auto flex items-center justify-start rounded-md">
|
||||
<div className="flex items-center pr-1.5 text-sm text-muted-foreground">
|
||||
<div className="flex items-center pr-1.5 text-[13px] font-semibold text-muted-foreground">
|
||||
Select
|
||||
</div>
|
||||
<div className="flex items-center justify-center rounded-md bg-border p-1">
|
||||
<div className="flex items-center justify-center rounded-md">
|
||||
<ForwardedIconComponent
|
||||
name="corner-down-left"
|
||||
className="h-3 w-3 text-muted-foreground"
|
||||
className="h-3.5 w-3.5 text-muted-foreground"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -129,7 +141,9 @@ const ListSelectionComponent = ({
|
|||
selectedList = [],
|
||||
options,
|
||||
limit = 1,
|
||||
}: ListSelectionComponentProps) => {
|
||||
...baseInputProps
|
||||
}: InputProps<any, ListSelectionComponentProps>) => {
|
||||
const { nodeClass } = baseInputProps;
|
||||
const [search, setSearch] = useState("");
|
||||
const [hoveredItem, setHoveredItem] = useState<any | null>(null);
|
||||
const [focusedIndex, setFocusedIndex] = useState<number>(-1);
|
||||
|
|
@ -263,28 +277,33 @@ const ListSelectionComponent = ({
|
|||
return (
|
||||
<Dialog open={open} onOpenChange={(isOpen) => !isOpen && onClose()}>
|
||||
<DialogContent
|
||||
className="flex max-h-[65vh] min-h-[15vh] flex-col rounded-xl"
|
||||
className="flex max-h-[65vh] min-h-[15vh] flex-col rounded-xl p-0"
|
||||
onKeyDown={handleKeyDown}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<SearchBarComponent
|
||||
searchCategories={searchCategories}
|
||||
search={search}
|
||||
setSearch={setSearch}
|
||||
/>
|
||||
<Button
|
||||
unstyled
|
||||
size="icon"
|
||||
className="ml-auto h-[38px]"
|
||||
onClick={onClose}
|
||||
>
|
||||
<ForwardedIconComponent name="x" />
|
||||
</Button>
|
||||
</div>
|
||||
<DialogHeader className="flex w-full justify-between border-b px-3 py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<ForwardedIconComponent
|
||||
name={nodeClass?.icon || "unknown"}
|
||||
className="h-[18px] w-[18px] text-muted-foreground"
|
||||
/>
|
||||
<div className="text-[13px] font-semibold">
|
||||
{nodeClass?.display_name}
|
||||
</div>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
{(filteredList?.length > 20 || search) && (
|
||||
<div className="flex w-full items-center justify-between px-3">
|
||||
<SearchBarComponent
|
||||
searchCategories={searchCategories}
|
||||
search={search}
|
||||
setSearch={setSearch}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div
|
||||
ref={listContainerRef}
|
||||
className="flex flex-col gap-1 overflow-y-auto"
|
||||
className="flex w-full flex-col gap-1 overflow-y-auto px-3 pb-3"
|
||||
>
|
||||
{filteredList.length > 0 ? (
|
||||
filteredList.map((item, index) => (
|
||||
|
|
|
|||
|
|
@ -152,6 +152,7 @@ export default function NodeInputField({
|
|||
title,
|
||||
nodeId: data.id,
|
||||
isFlexView,
|
||||
required,
|
||||
})}
|
||||
</span>
|
||||
}
|
||||
|
|
@ -165,13 +166,13 @@ export default function NodeInputField({
|
|||
title,
|
||||
nodeId: data.id,
|
||||
isFlexView,
|
||||
required,
|
||||
})}
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<span className={"text-status-red"}>{required ? "*" : ""}</span>
|
||||
<div>
|
||||
{info !== "" && (
|
||||
<ShadTooltip content={<NodeInputInfo info={info} />}>
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ const RenderInputParameters = ({
|
|||
return keyMap;
|
||||
}, [templateFields, data.id, data.node?.template]);
|
||||
|
||||
console.log({ data });
|
||||
|
||||
const renderInputParameter = templateFields.map(
|
||||
(templateField: string, idx) => {
|
||||
const template = data.node?.template[templateField];
|
||||
|
|
|
|||
|
|
@ -250,8 +250,6 @@ function GenericNode({
|
|||
[data.node?.outputs],
|
||||
);
|
||||
|
||||
console.log(shownOutputs, hiddenOutputs);
|
||||
|
||||
const [hasChangedNodeDescription, setHasChangedNodeDescription] =
|
||||
useState(false);
|
||||
|
||||
|
|
|
|||
|
|
@ -236,6 +236,7 @@ const ConnectionComponent = ({
|
|||
setSelectedList={setSelectedItem}
|
||||
selectedList={selectedItem}
|
||||
options={options}
|
||||
{...baseInputProps}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const SearchBarComponent = ({
|
|||
};
|
||||
|
||||
return (
|
||||
<div className="mr-10 flex w-full items-center rounded-md border">
|
||||
<div className="flex w-full items-center rounded-md border">
|
||||
{searchCategories && searchCategories.length > 0 && (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const SortableListItem = memo(
|
|||
<li
|
||||
className={cn(
|
||||
"inline-flex h-12 w-full items-center gap-2 text-sm font-medium text-gray-800",
|
||||
limit === 1 ? "h-10 rounded-md bg-muted" : "group cursor-grab",
|
||||
limit === 1 ? "h-6 rounded-md bg-muted" : "group cursor-grab",
|
||||
)}
|
||||
>
|
||||
{limit !== 1 && (
|
||||
|
|
@ -52,8 +52,8 @@ const SortableListItem = memo(
|
|||
|
||||
<span
|
||||
className={cn(
|
||||
"truncate text-primary",
|
||||
limit === 1 ? "max-w-56 pl-3" : "max-w-48",
|
||||
"truncate text-muted-foreground",
|
||||
limit === 1 ? "max-w-56 pl-2" : "max-w-48",
|
||||
)}
|
||||
>
|
||||
{data.name}
|
||||
|
|
@ -63,9 +63,9 @@ const SortableListItem = memo(
|
|||
size="icon"
|
||||
variant={limit !== 1 ? "outline" : "ghost"}
|
||||
className={cn(
|
||||
"ml-auto h-7 w-7 opacity-0 transition-opacity duration-200",
|
||||
"ml-auto h-6 w-6 opacity-0 transition-opacity duration-200",
|
||||
limit === 1
|
||||
? "group pr-3 opacity-100"
|
||||
? "group pr-1 opacity-100"
|
||||
: "hover:border hover:border-destructive hover:bg-transparent hover:opacity-100",
|
||||
)}
|
||||
onClick={onRemove}
|
||||
|
|
@ -192,6 +192,7 @@ const SortableListComponent = ({
|
|||
selectedList={listData}
|
||||
options={options}
|
||||
limit={limit}
|
||||
{...baseInputProps}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ const DialogContent = React.forwardRef<
|
|||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-contentHide data-[state=open]:animate-contentShow",
|
||||
"fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-3 rounded-xl border bg-background p-3 shadow-lg duration-200 data-[state=closed]:animate-contentHide data-[state=open]:animate-contentShow",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ test("IntComponent", { tag: ["@release", "@workspace"] }, async ({ page }) => {
|
|||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
).toBeFalsy();
|
||||
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').click();
|
||||
expect(
|
||||
|
|
@ -108,7 +108,7 @@ test("IntComponent", { tag: ["@release", "@workspace"] }, async ({ page }) => {
|
|||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeFalsy();
|
||||
).toBeTruthy();
|
||||
|
||||
await page.locator('//*[@id="showmodel_kwargs"]').click();
|
||||
expect(
|
||||
|
|
@ -128,7 +128,7 @@ test("IntComponent", { tag: ["@release", "@workspace"] }, async ({ page }) => {
|
|||
await page.locator('//*[@id="showtemperature"]').click();
|
||||
expect(
|
||||
await page.locator('//*[@id="showtemperature"]').isChecked(),
|
||||
).toBeTruthy();
|
||||
).toBeFalsy();
|
||||
|
||||
await page.getByText("Close").last().click();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue