Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(chat): Marketplace no results found and Suggested results (Issue #2308) #2430

Merged
merged 13 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions apps/chat/src/components/Common/NoResultsFound.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import { useTranslation } from 'next-i18next';

import classNames from 'classnames';

import { Translation } from '@/src/types/translation';

import Magnifier from '../../../public/images/icons/search-alt.svg';

export const NoResultsFound = () => {
interface NoResultsFoundProps {
iconSize?: number;
className?: string;
}

export const NoResultsFound = ({
iconSize = 60,
className = 'text-sm gap-3',
}: NoResultsFoundProps) => {
const { t } = useTranslation(Translation.Common);

return (
<div
className="flex flex-col items-center justify-center gap-3"
className={classNames(
'flex flex-col items-center justify-center',
className,
)}
data-qa="no-data"
>
<Magnifier height={60} width={60} className="text-secondary" />
<Magnifier
height={iconSize}
width={iconSize}
className="text-secondary"
/>
<span>{t('No results found')}</span>
</div>
);
Expand Down
26 changes: 17 additions & 9 deletions apps/chat/src/components/Marketplace/ApplicationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ import { DialAIEntityModel } from '@/src/types/models';
import { Translation } from '@/src/types/translation';

import { useAppSelector } from '@/src/store/hooks';
import { MarketplaceSelectors } from '@/src/store/marketplace/marketplace.reducers';

import { MarketplaceTabs } from '@/src/constants/marketplace';
import { ModelsSelectors } from '@/src/store/models/models.reducers';

import { ModelIcon } from '@/src/components/Chatbar/ModelIcon';
import ContextMenu from '@/src/components/Common/ContextMenu';
Expand Down Expand Up @@ -81,12 +79,14 @@ export const ApplicationCard = ({
}: ApplicationCardProps) => {
const { t } = useTranslation(Translation.Marketplace);

const selectedTab = useAppSelector(MarketplaceSelectors.selectSelectedTab);

const isMyEntity = entity.id.startsWith(
getRootId({ featureType: FeatureType.Application }),
);

const installedModelIds = useAppSelector(
ModelsSelectors.selectInstalledModelIds,
);

const menuItems: DisplayMenuItemProps[] = useMemo(
() => [
{
Expand Down Expand Up @@ -135,9 +135,7 @@ export const ApplicationCard = ({
name: t('Remove'),
dataQa: 'remove',
display:
!isMyEntity &&
selectedTab === MarketplaceTabs.MY_APPLICATIONS &&
!!onRemove,
!isMyEntity && installedModelIds.has(entity.reference) && !!onRemove,
Icon: (props: TablerIconsProps) => (
<IconTrashX {...props} className="stroke-error" />
),
Expand All @@ -147,7 +145,17 @@ export const ApplicationCard = ({
},
},
],
[entity, onPublish, t, selectedTab, onDelete, isMyEntity, onEdit, onRemove],

Derikyan marked this conversation as resolved.
Show resolved Hide resolved
[
t,
isMyEntity,
onEdit,
onPublish,
entity,
onDelete,
installedModelIds,
onRemove,
],
);

const iconSize =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import { FeatureType } from '@/src/types/common';
import { DialAIEntityModel } from '@/src/types/models';
import { Translation } from '@/src/types/translation';

import { useAppSelector } from '@/src/store/hooks';
import { ModelsSelectors } from '@/src/store/models/models.reducers';

import { ModelVersionSelect } from '../../Chat/ModelVersionSelect';
import Tooltip from '../../Common/Tooltip';

Expand All @@ -35,7 +38,6 @@ interface Props {
export const ApplicationDetailsFooter = ({
entity,
allVersions,
isMyAppsTab,
onChangeVersion,
onPublish,
onUseEntity,
Expand All @@ -49,6 +51,9 @@ export const ApplicationDetailsFooter = ({
getRootId({ featureType: FeatureType.Application }),
);
const isPublicApp = isEntityPublic(entity);
const installedModelIds = useAppSelector(
ModelsSelectors.selectInstalledModelIds,
);

return (
<section className="flex px-3 py-4 md:px-6">
Expand All @@ -58,7 +63,7 @@ export const ApplicationDetailsFooter = ({
className="shrink-0 text-accent-primary md:hidden [&_path]:fill-current"
size={24}
/> */}
{(isMyAppsTab || isMyApp) && (
{(isMyApp || installedModelIds.has(entity.reference)) && (
<Tooltip tooltip={isMyApp ? t('Delete') : t('Remove')}>
<button
onClick={() => (isMyApp ? onDelete(entity) : onRemove(entity))}
Expand Down
2 changes: 1 addition & 1 deletion apps/chat/src/components/Marketplace/Marketplace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const Marketplace = () => {

return (
<div
className="grow overflow-auto px-3 py-4 md:p-5 xl:px-16 xl:py-6"
className="flex grow flex-col overflow-auto px-3 py-4 md:p-5 xl:px-16 xl:py-6"
data-qa="marketplace"
>
{isLoading ? (
Expand Down
83 changes: 67 additions & 16 deletions apps/chat/src/components/Marketplace/TabRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useCallback, useMemo, useState } from 'react';

import { useTranslation } from 'next-i18next';

import { isQuickApp } from '@/src/utils/app/application';
import { groupModelsAndSaveOrder } from '@/src/utils/app/conversation';
import { getFolderIdFromEntityId } from '@/src/utils/app/folders';
Expand All @@ -15,6 +17,7 @@ import {
import { ScreenState } from '@/src/types/common';
import { DialAIEntityModel } from '@/src/types/models';
import { SharingType } from '@/src/types/share';
import { Translation } from '@/src/types/translation';

import { ApplicationActions } from '@/src/store/application/application.reducers';
import { useAppDispatch, useAppSelector } from '@/src/store/hooks';
Expand All @@ -39,6 +42,9 @@ import { CardsList } from '@/src/components/Marketplace/CardsList';
import { MarketplaceBanner } from '@/src/components/Marketplace/MarketplaceBanner';
import { SearchHeader } from '@/src/components/Marketplace/SearchHeader';

import Magnifier from '../../../public/images/icons/search-alt.svg';
import { NoResultsFound } from '../Common/NoResultsFound';

import { PublishActions, ShareEntity } from '@epam/ai-dial-shared';
import intersection from 'lodash-es/intersection';
import orderBy from 'lodash-es/orderBy';
Expand Down Expand Up @@ -81,6 +87,10 @@ interface TabRendererProps {
}

export const TabRenderer = ({ screenState }: TabRendererProps) => {
const { t } = useTranslation(Translation.Marketplace);
const [suggestedResults, setSuggestedResults] = useState<
DialAIEntityModel[] | null
>(null);
const dispatch = useAppDispatch();

const installedModelIds = useAppSelector(
Expand Down Expand Up @@ -135,15 +145,20 @@ export const TabRenderer = ({ screenState }: TabRendererProps) => {
)
: filteredEntities;

const groupedEntities = groupModelsAndSaveOrder(entitiesForTab).slice(
0,
Number.MAX_SAFE_INTEGER,
);

const groupedEntities = groupModelsAndSaveOrder(entitiesForTab);
const orderedEntities = groupedEntities.map(
({ entities }) => orderBy(entities, 'version', 'desc')[0],
);

if (
selectedTab === MarketplaceTabs.MY_APPLICATIONS &&
!entitiesForTab.length
) {
setSuggestedResults(filteredEntities);
} else {
setSuggestedResults(null);
}

return orderedEntities;
}, [installedModelIds, allModels, searchTerm, selectedFilters, selectedTab]);

Expand Down Expand Up @@ -242,23 +257,59 @@ export const TabRenderer = ({ screenState }: TabRendererProps) => {

return (
<>
<header className="mb-4" data-qa="marketplace-header">
<header className="mb-6" data-qa="marketplace-header">
<MarketplaceBanner />
<SearchHeader
items={displayedEntities.length}
onAddApplication={handleAddApplication}
/>
</header>

<CardsList
entities={displayedEntities}
onCardClick={handleSetDetailsReference}
onPublish={handleSetPublishEntity}
onDelete={handleDelete}
onRemove={handleRemove}
onEdit={handleEditApplication}
isNotDesktop={screenState !== ScreenState.DESKTOP}
/>
{displayedEntities.length > 0 ? (
<CardsList
entities={displayedEntities}
onCardClick={handleSetDetailsReference}
onPublish={handleSetPublishEntity}
onDelete={handleDelete}
onRemove={handleRemove}
onEdit={handleEditApplication}
isNotDesktop={screenState !== ScreenState.DESKTOP}
/>
) : (
<>
{selectedTab === MarketplaceTabs.MY_APPLICATIONS &&
suggestedResults?.length ? (
<>
<div className="mb-8 flex items-center gap-1">
<Magnifier height={32} width={32} className="text-secondary" />
<span className="text-base">
{t(
'No results found in My workspace. Look at suggested results from DIAL Marketplace.',
)}
</span>
</div>
<span className="text-xl">
{t('Suggested results from DIAL Marketplace')}
</span>
<CardsList
entities={suggestedResults}
onCardClick={handleSetDetailsReference}
onPublish={handleSetPublishEntity}
onDelete={handleDelete}
onRemove={handleRemove}
onEdit={handleEditApplication}
isNotDesktop={screenState !== ScreenState.DESKTOP}
/>
</>
) : (
<div className="flex grow flex-col items-center justify-center">
<NoResultsFound iconSize={100} className="gap-5 text-lg" />
<span className="mt-4 text-sm">
{t("Sorry, we couldn't find any results for your search.")}
</span>
</div>
)}
</>
)}

{/* MODALS */}
{!!(
Expand Down
Loading