Skip to content

Commit

Permalink
feat: update agent hub navigation and filtering (#321)
Browse files Browse the repository at this point in the history
* fix: Resolve mention dropdown issue in @ agent selection for light mode

* feat(chat): add rename and delete functionality to chat channels

Summary:
- Add rename and delete icons to chat channels with hover effects
- Implement channel rename functionality with inline editing
- Implement channel delete functionality with confirmation
- Update channel header to display current channel name
- Convert numeric IDs to string format for message handling
- Add blue and red color indicators for rename and delete actions

* feat: update agent hub navigation and filtering

- Redirect Agent Hub card to local development URL (http://localhost:3000/agents)
- Add agent category filtering functionality
- Remove hardcoded agent categories
- Add useState and useEffect hooks to fetch actual agent data
- Filter agents dynamically based on selected category
- Generate links with version info using real agent data
- Display all relevant agents when a category is selected

* feat: update agent hub navigation and filtering

* feat(chat): add new, rename and delete functionality to chat channels
  • Loading branch information
XiangZhang-zx authored Nov 17, 2024
1 parent a68b0b4 commit 4279cf7
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 102 deletions.
24 changes: 7 additions & 17 deletions agenthub/app/agents/ContentLayout/DatasetsHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,18 @@

import { FilterSVG, SortSVG } from '@/ui/svgs'
import { Input } from '@nextui-org/react'
import { AgentListGenerator } from '../const';
import { useState } from 'react'

import { useState, useEffect } from 'react'
interface DatasetsHeaderProps {
filteredCount?: number;
}

export function DatasetsHeader() {
useEffect(() => {
const _ = async () => {
const AgentList = await AgentListGenerator();
setAgentNumber(AgentList.length);
}

_();

}, []);

const [agentNumber, setAgentNumber] = useState(0);

export function DatasetsHeader({ filteredCount = 0 }: DatasetsHeaderProps) {
return (
<div className="mb-4 items-center space-y-3 md:flex md:space-y-0 lg:mb-6">
<div className="flex items-center text-lg">
<h1>Agents</h1>
<div className="ml-3 w-16 font-normal text-gray-400">{agentNumber}</div>
<div className="ml-3 w-16 font-normal text-gray-400">{filteredCount}</div>
</div>
<div className="flex-1 md:mx-4 opacity-0">
<div className="relative w-full md:max-w-xs">
Expand All @@ -44,7 +34,7 @@ export function DatasetsHeader() {
<div className="relative inline-block">
<button className=" btn w-full cursor-pointer text-sm" type="button">
<SortSVG />
Sort:  Trending
Sort: Trending
</button>
</div>
</div>
Expand Down
144 changes: 81 additions & 63 deletions agenthub/app/agents/TabsLayout/index.client.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,95 @@
'use client'

import { useState } from 'react'
import { useState, useEffect } from 'react'
import classNames from 'classnames'

import { DatasetsTabList } from '../const'
import { DatasetsTabItem } from '../type'

import FilterTab from './FilterTab'
import TabTasks from './TabTasks'
import TabOther from './TabOther'
import TabLicenses from './TabLicenses'
import TabLanguages from './TabLanguages'
import TabSubTasks from './TabSubTasks'
import TabSizes from './TabSizes'
import { ApplySVG, ExitSVG } from '@/ui/svgs'
import { AgentTabList } from '../const'
import { DatasetsTabItem, AgentItem } from '../type'
import { ExitSVG } from '@/ui/svgs'
import { baseUrl } from '@/lib/env'
import AgentCard from '../ContentLayout/AgentCard'
import { DatasetsHeader } from '../ContentLayout/DatasetsHeader'

export default function LeftTabsLayout() {
const [currentTab, setCurrentTab] = useState<DatasetsTabItem>('Tasks')
//linter
// const [isAddFilterModalDisplay, setIsAddFilterModalDisplay] = useState<boolean>(false)
const [currentTab, setCurrentTab] = useState<DatasetsTabItem>('Academic')
const [agents, setAgents] = useState<AgentItem[]>([])
const isAddFilterModalDisplay = false;

useEffect(() => {
const fetchAgents = async () => {
const res = await fetch(`${baseUrl}/api/get_all_agents/light`, { cache: 'no-store' });
const data = await res.json();
setAgents(Object.values(data));
};

fetchAgents();
}, []);

const onTabClick = (tabName: DatasetsTabItem) => {
setCurrentTab(tabName)
}

// Filter agents based on current selected category
const filteredAgents = agents.filter(agent => {
const name = agent.name.toLowerCase();
switch(currentTab) {
case 'Academic':
return name.includes('academic') || name.includes('math');
case 'Creative':
return name.includes('creator') || name.includes('designer') || name.includes('composer');
case 'Lifestyle':
return name.includes('therapist') || name.includes('trainer') || name.includes('mixologist');
case 'Entertainment':
return name.includes('entertainment') || name.includes('game');
default:
return true;
}
});

return (
<section
className={classNames(
'pt-8 border-gray-100 bg-white lg:static lg:px-0 lg:col-span-4 xl:col-span-3 lg:border-r lg:bg-gradient-to-l from-gray-50-to-white',
isAddFilterModalDisplay ? 'fixed overflow-y-auto overflow-x-hidden z-40 inset-0 !px-4 !pt-4' : 'hidden lg:block'
)}
>
<div className="mb-4 flex items-center justify-between lg:hidden">
<h3 className="text-base font-semibold">Edit Datasets filters</h3>
<button className="text-xl" type="button">
<ExitSVG />
</button>
</div>
<ul className="flex gap-1 text-sm flex-wrap mt-1.5 mb-5">
{DatasetsTabList.map((tabName, index) => (
<li key={index}>
<button
className={classNames(
'flex items-center whitespace-nowrap rounded-lg px-2',
currentTab === tabName
? 'bg-black text-white dark:bg-gray-800'
: 'text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-900 dark:hover:text-gray-300'
)}
onClick={() => {
onTabClick(tabName)
}}
>
{tabName}
</button>
</li>
))}
</ul>
<FilterTab />
<div className="mb-3">
{currentTab === 'Tasks' && <TabTasks />}
{currentTab === 'Sizes' && <TabSizes />}
{currentTab === 'Sub-tasks' && <TabSubTasks />}
{currentTab === 'Languages' && <TabLanguages />}
{currentTab === 'Licenses' && <TabLicenses />}
{currentTab === 'Other' && <TabOther />}
</div>
<div className="fixed inset-x-4 bottom-0 flex h-16 items-center border-t bg-white dark:bg-gray-950 lg:hidden">
<button className="btn btn-lg -mt-px w-full font-semibold" type="button">
<ApplySVG />
Apply filters
</button>
</div>
</section>
<>
<section
className={classNames(
'pt-8 border-gray-100 bg-white lg:static lg:px-0 lg:col-span-4 xl:col-span-3 lg:border-r lg:bg-gradient-to-l from-gray-50-to-white',
isAddFilterModalDisplay ? 'fixed overflow-y-auto overflow-x-hidden z-40 inset-0 !px-4 !pt-4' : ''
)}
>
{/* Left sidebar category menu */}
<div className="mb-4 flex items-center justify-between lg:hidden">
<h3 className="text-base font-semibold">Agent Categories</h3>
<button className="text-xl" type="button">
<ExitSVG />
</button>
</div>
<ul className="flex gap-1 text-sm flex-wrap mt-1.5 mb-5">
{AgentTabList.map((tabName, index) => (
<li key={index}>
<button
className={classNames(
'flex items-center whitespace-nowrap rounded-lg px-3 py-1.5',
currentTab === tabName
? 'bg-black text-white dark:bg-gray-800'
: 'text-gray-500 hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-900 dark:hover:text-gray-300'
)}
onClick={() => {
onTabClick(tabName)
}}
>
{tabName}
</button>
</li>
))}
</ul>
</section>

{/* Main content section with filtered agents */}
<section className="pt-8 col-span-full lg:col-span-6 xl:col-span-7 pb-12">
<DatasetsHeader filteredCount={filteredAgents.length} />
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3">
{filteredAgents.map((agent) => (
<AgentCard key={agent.id} item={agent} />
))}
</div>
</section>
</>
)
}
27 changes: 21 additions & 6 deletions agenthub/app/agents/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,33 @@ export const AgentList: AgentItem[] = [];
// export const AgentList =

export const AgentListGenerator: () => Promise<AgentItem[]> = async () => {
const res = await fetch(`${baseUrl}/api/get_all_agents/light`, { cache: 'no-store' });
const res_ = await res.json();
try {
const res = await fetch(`${baseUrl}/api/get_all_agents/light`, { cache: 'no-store' });
const res_ = await res.json();

const values: AgentItem[] = Object.values(res_);
if (!res_ || typeof res_ !== 'object') {
console.error('Invalid response format:', res_);
return [];
}

console.log('length', res_)
const values: AgentItem[] = Object.values(res_);
console.log('Response data:', res_);
console.log('Parsed values:', values);

return values;
return values;
} catch (error) {
console.error('Error fetching agents:', error);
return [];
}
}

// export const DatasetsTabList: DatasetsTabItem[] = ['Tasks', 'Sizes', 'Sub-tasks', 'Languages', 'Licenses', 'Other']
export const AgentTabList: DatasetsTabItem[] = ['Recommended', 'Writing', 'Entertainment', 'Programming']
export const AgentTabList: DatasetsTabItem[] = [
'Academic',
'Creative',
'Lifestyle',
'Entertainment'
]

export const DatasetOther = [
'Trained with AutoTrain',
Expand Down
17 changes: 6 additions & 11 deletions agenthub/app/agents/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import TabsLayout from './TabsLayout/index.client'
import ContentLayout from './ContentLayout'
import LeftTabsLayout from './TabsLayout/index.client'

export default function Datasets({ searchParams }:
{ searchParams: { [key: string]: string | string[] | undefined } }) {
export default function Datasets() {
return (
<main className="flex flex-1 flex-col">
<div className="SVELTE_HYDRATER contents" data-props="" data-target="DatasetList">
<div className="container relative flex flex-col lg:grid lg:space-y-0 w-full lg:grid-cols-10 md:flex-1 md:grid-rows-full md:gap-6 ">
<TabsLayout />
<ContentLayout searchParams={searchParams} />
</div>
<div className="flex min-h-[calc(100vh_-_64px)]">
<div className="container relative flex flex-col lg:grid lg:space-y-0 w-full lg:grid-cols-10 md:flex-1 md:grid-rows-full md:gap-6">
<LeftTabsLayout />
</div>
</main>
</div>
)
}
4 changes: 2 additions & 2 deletions agenthub/app/agents/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export interface DatasetItem {
favorites: string
}

export type DatasetsTabItem = 'Recommended' | 'Writing' | 'Entertainment' | 'Programming' | 'Tasks' | 'Sizes' | 'Sub-tasks' | 'Languages' | 'Licenses' | 'Other';
export type DatasetsTabItem = 'Recommended' | 'Writing' | 'Entertainment' | 'Programming' | 'Tasks' | 'Sizes' | 'Sub-tasks' | 'Languages' | 'Licenses' | 'Other' | 'Academic' | 'Creative' | 'Lifestyle' | 'Entertainment';

export type AgentTabItem = 'Tasks' | 'Sizes' | 'Sub-tasks' | 'Languages' | 'Licenses' | 'Other'
export type AgentTabItem = 'Tasks' | 'Sizes' | 'Sub-tasks' | 'Languages' | 'Licenses' | 'Other' | 'Academic' | 'Creative' | 'Lifestyle' | 'Entertainment';


export interface AgentItem {
Expand Down
2 changes: 1 addition & 1 deletion agenthub/components/homepage/Products.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Examples = [
author_url: 'https://github.com/vercel',
author_img: 'https://avatars.githubusercontent.com/u/14985020',
repo_name: 'vercel/nextjs-subscription-payments',
repo_url: 'https://my.aios.foundation/agents',
repo_url: 'http://localhost:3000/agents',
vercel_deploy_url:
'https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnextjs-subscription-payments&env=NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY,STRIPE_SECRET_KEY&envDescription=Enter%20your%20Stripe%20API%20keys.&envLink=https%3A%2F%2Fdashboard.stripe.com%2Fapikeys&project-name=nextjs-subscription-payments&repository-name=nextjs-subscription-payments&integration-ids=oac_VqOgBHqhEoFTPzGkPd7L0iH6&external-id=https%3A%2F%2Fgithub.com%2Fvercel%2Fnextjs-subscription-payments%2Ftree%2Fmain',
demo_url: 'https://subscription-payments.vercel.app/',
Expand Down
8 changes: 6 additions & 2 deletions agenthub/lib/env.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
export const inDevEnvironment = !!process && process.env.NODE_ENV === 'development';
// export const serverUrl = inDevEnvironment ? 'http://localhost:8000' : 'https://myapp-y5z35kuonq-uk.a.run.app'
export const baseUrl = inDevEnvironment ? 'http://localhost:3000' : 'https://my.aios.foundation'
export const baseUrl = process.env.NODE_ENV === 'development'
? 'http://localhost:3000'
: 'https://my.aios.foundation';
// export const serverUrl = inDevEnvironment ? 'http://localhost:8000' : 'http://35.232.56.61:8000'
export const serverUrl = 'http://35.232.56.61:8000';
export const serverUrl = process.env.NODE_ENV === 'development'
? 'http://localhost:8000'
: 'https://api.aios.chat';

0 comments on commit 4279cf7

Please sign in to comment.