mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 09:20:15 +01:00
chore: add missing SidePanelProvider for AgentMarketplace and organize imports
This commit is contained in:
parent
04af67951b
commit
5ca9da378b
1 changed files with 125 additions and 122 deletions
|
|
@ -1,25 +1,24 @@
|
||||||
import React, { useState, useEffect, useMemo } from 'react';
|
import React, { useState, useEffect, useMemo } from 'react';
|
||||||
import { useOutletContext } from 'react-router-dom';
|
import { useOutletContext } from 'react-router-dom';
|
||||||
import { useSearchParams, useParams, useNavigate } from 'react-router-dom';
|
|
||||||
import { useSetRecoilState, useRecoilValue } from 'recoil';
|
import { useSetRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
||||||
|
import { useSearchParams, useParams, useNavigate } from 'react-router-dom';
|
||||||
import type t from 'librechat-data-provider';
|
import type t from 'librechat-data-provider';
|
||||||
import type { ContextType } from '~/common';
|
import type { ContextType } from '~/common';
|
||||||
|
|
||||||
import { useGetEndpointsQuery, useGetAgentCategoriesQuery } from '~/data-provider';
|
import { useGetEndpointsQuery, useGetAgentCategoriesQuery } from '~/data-provider';
|
||||||
import { useDocumentTitle, useHasAccess } from '~/hooks';
|
|
||||||
import useLocalize from '~/hooks/useLocalize';
|
|
||||||
import { TooltipAnchor, Button } from '~/components/ui';
|
|
||||||
import { NewChatIcon } from '~/components/svg';
|
|
||||||
import { OpenSidebar } from '~/components/Chat/Menus';
|
|
||||||
import { SidePanelGroup } from '~/components/SidePanel';
|
|
||||||
import { MarketplaceProvider } from './MarketplaceContext';
|
import { MarketplaceProvider } from './MarketplaceContext';
|
||||||
|
import { useDocumentTitle, useHasAccess } from '~/hooks';
|
||||||
|
import { TooltipAnchor, Button } from '~/components/ui';
|
||||||
|
import { SidePanelGroup } from '~/components/SidePanel';
|
||||||
|
import { OpenSidebar } from '~/components/Chat/Menus';
|
||||||
|
import { SidePanelProvider } from '~/Providers';
|
||||||
|
import { NewChatIcon } from '~/components/svg';
|
||||||
|
import useLocalize from '~/hooks/useLocalize';
|
||||||
import CategoryTabs from './CategoryTabs';
|
import CategoryTabs from './CategoryTabs';
|
||||||
import AgentDetail from './AgentDetail';
|
import AgentDetail from './AgentDetail';
|
||||||
import SearchBar from './SearchBar';
|
import SearchBar from './SearchBar';
|
||||||
import AgentGrid from './AgentGrid';
|
import AgentGrid from './AgentGrid';
|
||||||
import store from '~/store';
|
import store from '~/store';
|
||||||
import { PermissionTypes, Permissions } from 'librechat-data-provider';
|
|
||||||
|
|
||||||
interface AgentMarketplaceProps {
|
interface AgentMarketplaceProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
@ -191,128 +190,132 @@ const AgentMarketplace: React.FC<AgentMarketplaceProps> = ({ className = '' }) =
|
||||||
return (
|
return (
|
||||||
<div className={`relative flex w-full grow overflow-hidden bg-presentation ${className}`}>
|
<div className={`relative flex w-full grow overflow-hidden bg-presentation ${className}`}>
|
||||||
<MarketplaceProvider>
|
<MarketplaceProvider>
|
||||||
<SidePanelGroup
|
<SidePanelProvider>
|
||||||
defaultLayout={defaultLayout}
|
<SidePanelGroup
|
||||||
fullPanelCollapse={fullCollapse}
|
defaultLayout={defaultLayout}
|
||||||
defaultCollapsed={defaultCollapsed}
|
fullPanelCollapse={fullCollapse}
|
||||||
>
|
defaultCollapsed={defaultCollapsed}
|
||||||
<main className="flex h-full flex-col overflow-y-auto" role="main">
|
>
|
||||||
{/* Simplified header for agents marketplace - only show nav controls when needed */}
|
<main className="flex h-full flex-col overflow-y-auto" role="main">
|
||||||
<div className="sticky top-0 z-10 flex h-14 w-full items-center justify-between bg-white p-2 font-semibold text-text-primary dark:bg-gray-800">
|
{/* Simplified header for agents marketplace - only show nav controls when needed */}
|
||||||
<div className="mx-1 flex items-center gap-2">
|
<div className="sticky top-0 z-10 flex h-14 w-full items-center justify-between bg-white p-2 font-semibold text-text-primary dark:bg-gray-800">
|
||||||
{!navVisible && <OpenSidebar setNavVisible={setNavVisible} />}
|
<div className="mx-1 flex items-center gap-2">
|
||||||
{!navVisible && (
|
{!navVisible && <OpenSidebar setNavVisible={setNavVisible} />}
|
||||||
<TooltipAnchor
|
{!navVisible && (
|
||||||
description={localize('com_ui_new_chat')}
|
<TooltipAnchor
|
||||||
render={
|
description={localize('com_ui_new_chat')}
|
||||||
<Button
|
render={
|
||||||
size="icon"
|
<Button
|
||||||
variant="outline"
|
size="icon"
|
||||||
data-testid="agents-new-chat-button"
|
variant="outline"
|
||||||
aria-label={localize('com_ui_new_chat')}
|
data-testid="agents-new-chat-button"
|
||||||
className="rounded-xl border border-border-light bg-surface-secondary p-2 hover:bg-surface-hover max-md:hidden"
|
aria-label={localize('com_ui_new_chat')}
|
||||||
onClick={handleNewChat}
|
className="rounded-xl border border-border-light bg-surface-secondary p-2 hover:bg-surface-hover max-md:hidden"
|
||||||
>
|
onClick={handleNewChat}
|
||||||
<NewChatIcon />
|
>
|
||||||
</Button>
|
<NewChatIcon />
|
||||||
}
|
</Button>
|
||||||
/>
|
}
|
||||||
)}
|
/>
|
||||||
</div>
|
)}
|
||||||
</div>
|
|
||||||
<div className="container mx-auto max-w-4xl px-4 py-8">
|
|
||||||
{/* Hero Section - ChatGPT Style */}
|
|
||||||
<div className="mb-8 mt-12 text-center">
|
|
||||||
<h1 className="mb-3 text-5xl font-bold tracking-tight text-gray-900 dark:text-white">
|
|
||||||
{localize('com_agents_marketplace')}
|
|
||||||
</h1>
|
|
||||||
<p className="mx-auto mb-6 max-w-2xl text-lg text-gray-600 dark:text-gray-300">
|
|
||||||
{localize('com_agents_marketplace_subtitle')}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{/* Search bar */}
|
|
||||||
<div className="mx-auto max-w-2xl">
|
|
||||||
<SearchBar value={searchQuery} onSearch={handleSearch} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="container mx-auto max-w-4xl px-4 py-8">
|
||||||
|
{/* Hero Section - ChatGPT Style */}
|
||||||
|
<div className="mb-8 mt-12 text-center">
|
||||||
|
<h1 className="mb-3 text-5xl font-bold tracking-tight text-gray-900 dark:text-white">
|
||||||
|
{localize('com_agents_marketplace')}
|
||||||
|
</h1>
|
||||||
|
<p className="mx-auto mb-6 max-w-2xl text-lg text-gray-600 dark:text-gray-300">
|
||||||
|
{localize('com_agents_marketplace_subtitle')}
|
||||||
|
</p>
|
||||||
|
|
||||||
{/* Category tabs */}
|
{/* Search bar */}
|
||||||
<CategoryTabs
|
<div className="mx-auto max-w-2xl">
|
||||||
categories={categoriesQuery.data || []}
|
<SearchBar value={searchQuery} onSearch={handleSearch} />
|
||||||
activeTab={activeTab}
|
</div>
|
||||||
isLoading={categoriesQuery.isLoading}
|
</div>
|
||||||
onChange={handleTabChange}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{/* Category header - only show when not searching */}
|
{/* Category tabs */}
|
||||||
{!searchQuery && (
|
<CategoryTabs
|
||||||
<div className="mb-6">
|
categories={categoriesQuery.data || []}
|
||||||
{(() => {
|
activeTab={activeTab}
|
||||||
// Get category data for display
|
isLoading={categoriesQuery.isLoading}
|
||||||
const getCategoryData = () => {
|
onChange={handleTabChange}
|
||||||
if (activeTab === 'promoted') {
|
/>
|
||||||
|
|
||||||
|
{/* Category header - only show when not searching */}
|
||||||
|
{!searchQuery && (
|
||||||
|
<div className="mb-6">
|
||||||
|
{(() => {
|
||||||
|
// Get category data for display
|
||||||
|
const getCategoryData = () => {
|
||||||
|
if (activeTab === 'promoted') {
|
||||||
|
return {
|
||||||
|
name: localize('com_agents_top_picks'),
|
||||||
|
description: localize('com_agents_recommended'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (activeTab === 'all') {
|
||||||
|
return {
|
||||||
|
name: 'All Agents',
|
||||||
|
description: 'Browse all shared agents across all categories',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the category in the API data
|
||||||
|
const categoryData = categoriesQuery.data?.find(
|
||||||
|
(cat) => cat.value === activeTab,
|
||||||
|
);
|
||||||
|
if (categoryData) {
|
||||||
|
return {
|
||||||
|
name: categoryData.label,
|
||||||
|
description: categoryData.description || '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback for unknown categories
|
||||||
return {
|
return {
|
||||||
name: localize('com_agents_top_picks'),
|
name: activeTab.charAt(0).toUpperCase() + activeTab.slice(1),
|
||||||
description: localize('com_agents_recommended'),
|
description: '',
|
||||||
};
|
};
|
||||||
}
|
|
||||||
if (activeTab === 'all') {
|
|
||||||
return {
|
|
||||||
name: 'All Agents',
|
|
||||||
description: 'Browse all shared agents across all categories',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the category in the API data
|
|
||||||
const categoryData = categoriesQuery.data?.find(
|
|
||||||
(cat) => cat.value === activeTab,
|
|
||||||
);
|
|
||||||
if (categoryData) {
|
|
||||||
return {
|
|
||||||
name: categoryData.label,
|
|
||||||
description: categoryData.description || '',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback for unknown categories
|
|
||||||
return {
|
|
||||||
name: activeTab.charAt(0).toUpperCase() + activeTab.slice(1),
|
|
||||||
description: '',
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const { name, description } = getCategoryData();
|
const { name, description } = getCategoryData();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="text-left">
|
<div className="text-left">
|
||||||
<h2 className="text-2xl font-bold text-gray-900 dark:text-white">{name}</h2>
|
<h2 className="text-2xl font-bold text-gray-900 dark:text-white">
|
||||||
{description && (
|
{name}
|
||||||
<p className="mt-2 text-gray-600 dark:text-gray-300">{description}</p>
|
</h2>
|
||||||
)}
|
{description && (
|
||||||
</div>
|
<p className="mt-2 text-gray-600 dark:text-gray-300">{description}</p>
|
||||||
);
|
)}
|
||||||
})()}
|
</div>
|
||||||
</div>
|
);
|
||||||
|
})()}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Agent grid */}
|
||||||
|
<AgentGrid
|
||||||
|
category={activeTab}
|
||||||
|
searchQuery={searchQuery}
|
||||||
|
onSelectAgent={handleAgentSelect}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Agent detail dialog */}
|
||||||
|
{isDetailOpen && selectedAgent && (
|
||||||
|
<AgentDetail
|
||||||
|
agent={selectedAgent}
|
||||||
|
isOpen={isDetailOpen}
|
||||||
|
onClose={handleDetailClose}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
|
</main>
|
||||||
{/* Agent grid */}
|
</SidePanelGroup>
|
||||||
<AgentGrid
|
</SidePanelProvider>
|
||||||
category={activeTab}
|
|
||||||
searchQuery={searchQuery}
|
|
||||||
onSelectAgent={handleAgentSelect}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Agent detail dialog */}
|
|
||||||
{isDetailOpen && selectedAgent && (
|
|
||||||
<AgentDetail
|
|
||||||
agent={selectedAgent}
|
|
||||||
isOpen={isDetailOpen}
|
|
||||||
onClose={handleDetailClose}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</main>
|
|
||||||
</SidePanelGroup>
|
|
||||||
</MarketplaceProvider>
|
</MarketplaceProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue