Skip to content

Commit 3b94010

Browse files
authored
Merge pull request #194 from DashHub-ai/feature/redesign-home
Redesign home
2 parents de173ea + 52cfb86 commit 3b94010

22 files changed

Lines changed: 301 additions & 94 deletions

File tree

apps/backend/src/modules/apps/elasticsearch/apps-es-search.repo.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,16 @@ export class AppsEsSearchRepo {
9393
})
9494
: TE.right([])),
9595
TE.bind('filtersWithMaybeFavorites', ({ favorites }) => {
96-
if (!favorites.length || !dto.favorites) {
96+
if (!dto.favorites) {
9797
return TE.right(dto);
9898
}
9999

100100
return TE.right({
101101
...dto,
102102
ids: [
103+
// trick for making the `ids` query generator always generate ids term query even if array is empty.
104+
// It'll make the query work properly when there is no favorites.
105+
-2,
103106
...(dto.ids ?? []),
104107
...pluckIds(favorites) as TableId[],
105108
],

apps/chat/src/i18n/packs/i18n-lang-en.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ export const I18N_PACK_EN = {
236236
title: 'DashHub Chat',
237237
},
238238
},
239+
home: {
240+
exploreApps: 'Explore Available Agents',
241+
meta: {
242+
title: 'Home',
243+
description: 'Welcome to DashHub Chat! Explore available agents and start a new chat.',
244+
},
245+
},
239246
login: {
240247
meta: {
241248
title: 'Login',

apps/chat/src/i18n/packs/i18n-lang-pl.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,13 @@ export const I18N_PACK_PL: I18nLangPack = {
238238
title: 'DashHub Chat',
239239
},
240240
},
241+
home: {
242+
exploreApps: 'Eksploruj dostępnych agentów',
243+
meta: {
244+
title: 'Strona Główna',
245+
description: 'Strona główna DashHub Chat',
246+
},
247+
},
241248
login: {
242249
meta: {
243250
title: 'Zaloguj się',

apps/chat/src/layouts/footer/footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function Footer() {
3636
{t.github}
3737
</a>
3838
<a
39-
href="https://dashhub.ai/blog"
39+
href="https://dashhub.ai/"
4040
target="_blank"
4141
rel="noopener noreferrer"
4242
className="flex items-center gap-2 text-gray-400 hover:text-gray-500"

apps/chat/src/layouts/navigation/links/navigation-links.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import clsx from 'clsx';
22
import {
33
FolderKanbanIcon,
44
HomeIcon,
5+
MessageSquareIcon,
56
PinIcon,
67
WandSparklesIcon,
78
} from 'lucide-react';
@@ -32,9 +33,8 @@ export function NavigationLinks({ inMobileMenu = false }: NavigationLinksProps)
3233
)}
3334
>
3435
<NavigationItem
35-
path={sitemap.chats.index}
36+
path={sitemap.home}
3637
icon={<HomeIcon size={16} />}
37-
disabled={!hasOrganization}
3838
>
3939
{t.links.home}
4040
</NavigationItem>
@@ -47,6 +47,14 @@ export function NavigationLinks({ inMobileMenu = false }: NavigationLinksProps)
4747
{t.links.apps}
4848
</NavigationItem>
4949

50+
<NavigationItem
51+
path={sitemap.chats.index}
52+
icon={<MessageSquareIcon size={16} />}
53+
disabled={!hasOrganization}
54+
>
55+
{t.links.chats}
56+
</NavigationItem>
57+
5058
<NavigationItem
5159
path={sitemap.pinnedMessages.index.generate({})}
5260
icon={<PinIcon size={16} />}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './chat';
22
export * from './choose-app';
33
export * from './grid';
4+
export * from './promoted-apps';
45
export * from './sidebar';
56
export * from './use-cached-app-lookup';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './promoted-apps-container';
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { clsx } from 'clsx';
2+
import { flow } from 'fp-ts/lib/function';
3+
4+
import { useLastNonNullValue } from '@llm/commons-front';
5+
import {
6+
type SdkAppT,
7+
SdkSearchAppsInputV,
8+
useSdkForLoggedIn,
9+
} from '@llm/sdk';
10+
import { LazyIcon } from '~/modules/shared';
11+
import { useWorkspaceOrganizationOrThrow } from '~/modules/workspace';
12+
import {
13+
CardSkeletonGrid,
14+
PaginatedList,
15+
SelectableBadges,
16+
SelectableBadgesSkeleton,
17+
useDebouncedPaginatedSearch,
18+
} from '~/ui';
19+
20+
import { AppCard } from '../grid/app-card';
21+
import { AppsPlaceholder } from '../grid/apps-placeholder';
22+
23+
type Props = {
24+
title?: string;
25+
limit?: number;
26+
className?: string;
27+
};
28+
29+
export function PromotedAppsContainer({ title, limit = 3, className }: Props) {
30+
const { assignWorkspaceToFilters } = useWorkspaceOrganizationOrThrow();
31+
const { sdks } = useSdkForLoggedIn();
32+
33+
const { loading, pagination, result, silentReload } = useDebouncedPaginatedSearch({
34+
storeDataInUrl: false,
35+
schema: SdkSearchAppsInputV,
36+
fallbackSearchParams: {
37+
limit,
38+
},
39+
fetchResultsTask: flow(assignWorkspaceToFilters, sdks.dashboard.apps.search),
40+
});
41+
42+
const gridClassName = clsx(
43+
'gap-4 grid grid-cols-1',
44+
'lg:grid-cols-2 3xl:grid-cols-3',
45+
);
46+
47+
const categoriesTree = (useLastNonNullValue(result?.aggs?.categories) || []).map(category => ({
48+
...category,
49+
icon: <LazyIcon name={category.icon as any} size={16} />,
50+
}));
51+
52+
return (
53+
<div className={className}>
54+
{title && (
55+
<h2 className="mb-8 font-semibold text-xl">
56+
{title}
57+
</h2>
58+
)}
59+
60+
<div className="mb-6">
61+
{loading || !categoriesTree
62+
? (
63+
<SelectableBadgesSkeleton />
64+
)
65+
: (
66+
<SelectableBadges
67+
{...pagination.bind.path('categoriesIds', { input: val => val ?? [] })}
68+
items={categoriesTree}
69+
multiSelect
70+
visibilityLimit={5}
71+
/>
72+
)}
73+
</div>
74+
75+
<PaginatedList
76+
result={result}
77+
loading={loading}
78+
pagination={pagination.bind.entire()}
79+
withEmptyPlaceholder={false}
80+
loadingFallback={(
81+
<CardSkeletonGrid className={gridClassName} count={limit} />
82+
)}
83+
>
84+
{({ items, total }) => {
85+
if (!total) {
86+
return <AppsPlaceholder />;
87+
}
88+
89+
return (
90+
<div className={gridClassName}>
91+
{(items as SdkAppT[]).map(item => (
92+
<AppCard
93+
key={item.id}
94+
app={item}
95+
onAfterArchive={silentReload}
96+
onAfterUnarchive={silentReload}
97+
onAfterToggleFavorite={silentReload}
98+
/>
99+
))}
100+
</div>
101+
);
102+
}}
103+
</PaginatedList>
104+
</div>
105+
);
106+
}

apps/chat/src/modules/chats/favorite/chats-favorite-section.tsx

Lines changed: 0 additions & 43 deletions
This file was deleted.

apps/chat/src/modules/chats/favorite/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)