From 741025a46122748a9de5b58e302f6c3d84b471e1 Mon Sep 17 00:00:00 2001 From: Marco Beretta <81851188+berry-13@users.noreply.github.com> Date: Wed, 6 Aug 2025 01:47:29 +0200 Subject: [PATCH] feat: Introduce InfoHoverCard component and refactor enums for better organization --- client/src/components/Agents/AgentGrid.tsx | 15 ----------- client/src/components/Agents/Marketplace.tsx | 19 +++++++------ packages/client/src/common/enum.ts | 13 +++++++++ packages/client/src/common/index.ts | 10 ++----- packages/client/src/common/types.ts | 7 +---- .../client/src/components/InfoHoverCard.tsx | 27 +++++++++++++++++++ packages/client/src/components/Toast.tsx | 2 +- packages/client/src/components/index.ts | 1 + 8 files changed, 56 insertions(+), 38 deletions(-) create mode 100644 packages/client/src/common/enum.ts create mode 100644 packages/client/src/components/InfoHoverCard.tsx diff --git a/client/src/components/Agents/AgentGrid.tsx b/client/src/components/Agents/AgentGrid.tsx index df7b208da9..8f82082125 100644 --- a/client/src/components/Agents/AgentGrid.tsx +++ b/client/src/components/Agents/AgentGrid.tsx @@ -108,24 +108,9 @@ const AgentGrid: React.FC = ({ category, searchQuery, onSelectAg } }; - /** - * Get the appropriate title for the agents grid based on current state - */ - const getGridTitle = () => { - if (searchQuery) { - return localize('com_agents_results_for', { query: searchQuery }); - } - - return getCategoryDisplayName(category); - }; - // Loading skeleton component const loadingSkeleton = (
-
-
-
-
{Array(6) .fill(0) diff --git a/client/src/components/Agents/Marketplace.tsx b/client/src/components/Agents/Marketplace.tsx index 742cf57cd0..8b9357e679 100644 --- a/client/src/components/Agents/Marketplace.tsx +++ b/client/src/components/Agents/Marketplace.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useMemo, useRef } from 'react'; +import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react'; import { useRecoilState } from 'recoil'; import { useOutletContext } from 'react-router-dom'; import { useQueryClient } from '@tanstack/react-query'; @@ -124,15 +124,18 @@ const AgentMarketplace: React.FC = ({ className = '' }) = */ const orderedTabs = useMemo(() => { const dynamic = (categoriesQuery.data || []).map((c) => c.value); - // Ensure unique and stable order - const set = new Set(['promoted', 'all', ...dynamic]); + // Ensure unique and stable order - 'all' should be last to match server response + const set = new Set(['promoted', ...dynamic, 'all']); return Array.from(set); }, [categoriesQuery.data]); - const getTabIndex = (tab: string): number => { - const idx = orderedTabs.indexOf(tab); - return idx >= 0 ? idx : 0; - }; + const getTabIndex = useCallback( + (tab: string): number => { + const idx = orderedTabs.indexOf(tab); + return idx >= 0 ? idx : 0; + }, + [orderedTabs], + ); /** * Handle category tab selection changes with directional animation @@ -199,7 +202,7 @@ const AgentMarketplace: React.FC = ({ className = '' }) = return () => { window.clearTimeout(timeoutId); }; - }, [activeTab, displayCategory, isTransitioning, orderedTabs]); + }, [activeTab, displayCategory, isTransitioning, getTabIndex]); // No longer needed with keyframes diff --git a/packages/client/src/common/enum.ts b/packages/client/src/common/enum.ts new file mode 100644 index 0000000000..25d019b6d8 --- /dev/null +++ b/packages/client/src/common/enum.ts @@ -0,0 +1,13 @@ +export enum ESide { + Top = 'top', + Right = 'right', + Bottom = 'bottom', + Left = 'left', +} + +export enum NotificationSeverity { + INFO = 'info', + SUCCESS = 'success', + WARNING = 'warning', + ERROR = 'error', +} diff --git a/packages/client/src/common/index.ts b/packages/client/src/common/index.ts index 7a855f3c17..b702743e94 100644 --- a/packages/client/src/common/index.ts +++ b/packages/client/src/common/index.ts @@ -1,11 +1,5 @@ -export type { - TShowToast, - Option, - OptionWithIcon, - DropdownValueSetter, - MentionOption, -} from './types'; +export * from './types'; -export { NotificationSeverity } from './types'; +export * from './enum'; export type { MenuItemProps } from './menus'; diff --git a/packages/client/src/common/types.ts b/packages/client/src/common/types.ts index aaeb5f524b..824e288eae 100644 --- a/packages/client/src/common/types.ts +++ b/packages/client/src/common/types.ts @@ -1,9 +1,4 @@ -export enum NotificationSeverity { - INFO = 'info', - SUCCESS = 'success', - WARNING = 'warning', - ERROR = 'error', -} +import { NotificationSeverity } from './enum'; export type TShowToast = { message: string; diff --git a/packages/client/src/components/InfoHoverCard.tsx b/packages/client/src/components/InfoHoverCard.tsx new file mode 100644 index 0000000000..ab43b6dd18 --- /dev/null +++ b/packages/client/src/components/InfoHoverCard.tsx @@ -0,0 +1,27 @@ +import { CircleHelpIcon } from 'lucide-react'; +import { HoverCard, HoverCardTrigger, HoverCardPortal, HoverCardContent } from './HoverCard'; +import { ESide } from '~/common'; + +type InfoHoverCardProps = { + side?: ESide; + text: string; +}; + +const InfoHoverCard = ({ side, text }: InfoHoverCardProps) => { + return ( + + + {' '} + + + +
+

{text}

+
+
+
+
+ ); +}; + +export default InfoHoverCard; diff --git a/packages/client/src/components/Toast.tsx b/packages/client/src/components/Toast.tsx index 34ca1a0531..5b8311b077 100644 --- a/packages/client/src/components/Toast.tsx +++ b/packages/client/src/components/Toast.tsx @@ -1,5 +1,5 @@ import * as RadixToast from '@radix-ui/react-toast'; -import { NotificationSeverity } from '~/common/types'; +import { NotificationSeverity } from '~/common'; import { useToast } from '~/hooks'; export function Toast() { diff --git a/packages/client/src/components/index.ts b/packages/client/src/components/index.ts index f315a2ca16..3ef9361a9a 100644 --- a/packages/client/src/components/index.ts +++ b/packages/client/src/components/index.ts @@ -44,6 +44,7 @@ export { default as MultiSelect } from './MultiSelect'; export { default as DropdownPopup } from './DropdownPopup'; export { default as DelayedRender } from './DelayedRender'; export { default as ThemeSelector } from './ThemeSelector'; +export { default as InfoHoverCard } from './InfoHoverCard'; export { default as CheckboxButton } from './CheckboxButton'; export { default as DialogTemplate } from './DialogTemplate'; export { default as SelectDropDown } from './SelectDropDown';