From 753a8ecf13742a2c6dd7f3994cdeaeaa6ee7edd8 Mon Sep 17 00:00:00 2001 From: Ilya Bondar Date: Tue, 10 Dec 2024 18:15:02 +0100 Subject: [PATCH 01/12] chore(chat): add `bypass_ort` --- .github/workflows/pr.yml | 2 ++ .github/workflows/release.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 36a5ac3642..ab2a24aa01 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -12,3 +12,5 @@ jobs: run_tests: uses: epam/ai-dial-ci/.github/workflows/node_pr.yml@1.10.0 secrets: inherit + with: + bypass_ort: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 10882714cd..8c33b4b9db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,3 +12,5 @@ jobs: release: uses: epam/ai-dial-ci/.github/workflows/node_release.yml@1.10.0 secrets: inherit + with: + bypass_ort: true From 0612dd718d46470b6ca194ec93a588cc2d59d764 Mon Sep 17 00:00:00 2001 From: Ilya Bondar Date: Tue, 10 Dec 2024 22:26:23 +0100 Subject: [PATCH 02/12] use ort_version: 42.1.0 --- .github/workflows/pr.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index ab2a24aa01..e99e1bf869 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -13,4 +13,4 @@ jobs: uses: epam/ai-dial-ci/.github/workflows/node_pr.yml@1.10.0 secrets: inherit with: - bypass_ort: true + ort_version: 42.1.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8c33b4b9db..750d3e6c37 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,4 +13,4 @@ jobs: uses: epam/ai-dial-ci/.github/workflows/node_release.yml@1.10.0 secrets: inherit with: - bypass_ort: true + ort_version: 42.1.0 From 7abbfe57bdaa7f6b72f84b478fa78268f1a05d65 Mon Sep 17 00:00:00 2001 From: Derikyan Date: Mon, 27 Jan 2025 09:01:48 +0400 Subject: [PATCH 03/12] fix(chat): fix card design, add copy link and share in context menu (Issue #2943) --- .../Marketplace/ApplicationCard.tsx | 30 +- .../ApplicationCopyLink.tsx | 60 ++- .../ApplicationDetails/ApplicationFooter.tsx | 431 +++++++++++++----- .../ApplicationDetails/ApplicationHeader.tsx | 34 +- .../src/components/Marketplace/CardsList.tsx | 3 - .../components/Marketplace/TabRenderer.tsx | 13 +- 6 files changed, 397 insertions(+), 174 deletions(-) diff --git a/apps/chat/src/components/Marketplace/ApplicationCard.tsx b/apps/chat/src/components/Marketplace/ApplicationCard.tsx index 9ce75bf1a9..73499c127a 100644 --- a/apps/chat/src/components/Marketplace/ApplicationCard.tsx +++ b/apps/chat/src/components/Marketplace/ApplicationCard.tsx @@ -25,7 +25,6 @@ import { isExecutableApp, } from '@/src/utils/app/application'; import { isMyApplication } from '@/src/utils/app/id'; -import { isMediumScreen } from '@/src/utils/app/mobile'; import { isEntityIdPublic } from '@/src/utils/app/publications'; import { canWriteSharedWithMe } from '@/src/utils/app/share'; @@ -60,11 +59,11 @@ import UnpublishIcon from '@/public/images/icons/unpublish.svg'; import IconUserUnshare from '@/public/images/icons/unshare-user.svg'; import { Feature, PublishActions } from '@epam/ai-dial-shared'; +const MOBILE_ICON_SIZE = 40; +const TABLET_ICON_SIZE = 48; const DESKTOP_ICON_SIZE = 80; -const SMALL_ICON_SIZE = 48; -// TODO uncomment in #2943 -// const MOBILE_SHARE_ICON_SIZE = 16; +const MOBILE_SHARE_ICON_SIZE = 16; const TABLET_SHARE_ICON_SIZE = 20; const DESKTOP_SHARE_ICON_SIZE = 30; @@ -75,7 +74,7 @@ interface CardFooterProps { const CardFooter = ({ entity }: CardFooterProps) => { return ( <> - + {getModelShortDescription(entity)}
@@ -110,7 +109,6 @@ const getPlayerCaption = (entity: DialAIEntityModel) => { interface ApplicationCardProps { entity: DialAIEntityModel; - isNotDesktop?: boolean; onClick: (entity: DialAIEntityModel) => void; onPublish?: (entity: DialAIEntityModel, action: PublishActions) => void; onDelete?: (entity: DialAIEntityModel) => void; @@ -120,7 +118,6 @@ interface ApplicationCardProps { export const ApplicationCard = ({ entity, - isNotDesktop, onClick, onDelete, onEdit, @@ -151,10 +148,19 @@ export const ApplicationCard = ({ const isExecutable = isExecutableApp(entity) && (isMyApp || isAdmin || canWrite); - const shareIconSize = + const iconSize = screenState === ScreenState.DESKTOP - ? DESKTOP_SHARE_ICON_SIZE - : TABLET_SHARE_ICON_SIZE; + ? DESKTOP_ICON_SIZE + : screenState === ScreenState.TABLET + ? TABLET_ICON_SIZE + : MOBILE_ICON_SIZE; + + const shareIconSize = + screenState === ScreenState.MOBILE + ? MOBILE_SHARE_ICON_SIZE + : screenState === ScreenState.TABLET + ? TABLET_SHARE_ICON_SIZE + : DESKTOP_SHARE_ICON_SIZE; const PlayerIcon = useMemo(() => { switch (playerStatus) { @@ -317,8 +323,6 @@ export const ApplicationCard = ({ ], ); - const iconSize = - (isNotDesktop ?? isMediumScreen()) ? SMALL_ICON_SIZE : DESKTOP_ICON_SIZE; const Bookmark = installedModelIds.has(entity.reference) ? IconBookmarkFilled : IconBookmark; @@ -327,7 +331,7 @@ export const ApplicationCard = ({ <>
onClick(entity)} - className="group relative h-[162px] cursor-pointer rounded-md bg-layer-2 p-4 shadow-card hover:bg-layer-3 xl:h-[164px] xl:p-5" + className="group relative h-[98px] cursor-pointer rounded-md bg-layer-2 p-3 shadow-card hover:bg-layer-3 md:h-[162px] md:p-4 xl:h-[164px] xl:p-5" data-qa="agent" >
diff --git a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx index 0c7ab2a824..5058b2472c 100644 --- a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx +++ b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx @@ -3,28 +3,40 @@ import { MouseEvent, useCallback, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'next-i18next'; +import classNames from 'classnames'; + import { PageType } from '@/src/types/common'; -import { DialAIEntityModel } from '@/src/types/models'; import { Translation } from '@/src/types/translation'; import { MarketplaceQueryParams } from '@/src/constants/marketplace'; +import Tooltip from '../../Common/Tooltip'; + interface ApplicationCopyLinkProps { - entity: DialAIEntityModel; + reference: string; + size?: number; + withText?: boolean; + hasTooltip?: boolean; + className?: string; } -const ICON_SIZE = 20; const TRIGGER_CLASS = 'flex items-center gap-2 whitespace-nowrap px-3 py-1.5 text-sm text-accent-primary outline-none'; -export function ApplicationCopyLink({ entity }: ApplicationCopyLinkProps) { +export function ApplicationCopyLink({ + reference, + size = 20, + withText, + hasTooltip, + className, +}: ApplicationCopyLinkProps) { const { t } = useTranslation(Translation.Marketplace); const [urlCopied, setUrlCopied] = useState(false); const timeoutRef = useRef>(); const link = useMemo( () => - `${window.location.origin}/${PageType.Marketplace}?${MarketplaceQueryParams.model}=${entity.reference}`, - [entity.reference], + `${window.location.origin}/${PageType.Marketplace}?${MarketplaceQueryParams.model}=${reference}`, + [reference], ); const handleCopy = useCallback( (e: MouseEvent) => { @@ -43,23 +55,31 @@ export function ApplicationCopyLink({ entity }: ApplicationCopyLinkProps) { [link], ); + const Content = urlCopied ? ( +
+ + {withText && {t('Copied!')}} +
+ ) : ( + + + {withText && {t('Copy link')}} + + ); + return ( <> - {urlCopied ? ( -
- - {t('Copied!')} -
+ {hasTooltip ? ( + + {Content} + ) : ( - - - {t('Copy link')} - + Content )} ); diff --git a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx index 0dd22669f7..7caf59dae8 100644 --- a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx +++ b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx @@ -3,9 +3,11 @@ import { IconBookmarkFilled, IconEdit, IconFileDescription, + IconLink, IconPlayerPlay, IconPlaystationSquare, IconTrashX, + IconUserShare, IconWorldShare, } from '@tabler/icons-react'; import { useCallback, useMemo, useState } from 'react'; @@ -18,10 +20,12 @@ import { getApplicationNextStatus, getApplicationSimpleStatus, isApplicationDeploymentInProgress, + isApplicationPublic, isApplicationStatusUpdating, isExecutableApp, } from '@/src/utils/app/application'; import { isApplicationId, isMyApplication } from '@/src/utils/app/id'; +import { isSmallScreen } from '@/src/utils/app/mobile'; import { isEntityIdPublic } from '@/src/utils/app/publications'; import { canWriteSharedWithMe } from '@/src/utils/app/share'; @@ -29,6 +33,8 @@ import { ApplicationStatus, SimpleApplicationStatus, } from '@/src/types/applications'; +import { FeatureType, PageType } from '@/src/types/common'; +import { DisplayMenuItemProps } from '@/src/types/menu'; import { DialAIEntityModel } from '@/src/types/models'; import { Translation } from '@/src/types/translation'; @@ -38,13 +44,18 @@ import { useAppDispatch, useAppSelector } from '@/src/store/hooks'; import { ModelsSelectors } from '@/src/store/models/models.reducers'; import { SettingsSelectors } from '@/src/store/settings/settings.reducers'; import { ShareActions } from '@/src/store/share/share.reducers'; +import { UIActions } from '@/src/store/ui/ui.reducers'; -import Loader from '@/src/components/Common/Loader'; +import { MarketplaceQueryParams } from '@/src/constants/marketplace'; import { ModelVersionSelect } from '../../Chat/ModelVersionSelect'; +import ContextMenu from '../../Common/ContextMenu'; +import Loader from '../../Common/Loader'; import Tooltip from '../../Common/Tooltip'; import { ApplicationLogs } from '../ApplicationLogs'; +import { ApplicationCopyLink } from './ApplicationCopyLink'; +import LoaderIcon from '@/public/images/icons/loader.svg'; import UnpublishIcon from '@/public/images/icons/unpublish.svg'; import IconUserUnshare from '@/public/images/icons/unshare-user.svg'; import { Feature, PublishActions } from '@epam/ai-dial-shared'; @@ -112,7 +123,10 @@ export const ApplicationDetailsFooter = ({ const isMyApp = isMyApplication(entity); const isAdmin = useAppSelector(AuthSelectors.selectIsAdmin); - const isPublicApp = isEntityIdPublic(entity); + + const isPublicEntity = isEntityIdPublic(entity); + const isPublicApp = isApplicationPublic(entity); + const Bookmark = installedModelIds.has(entity.reference) ? IconBookmarkFilled : IconBookmark; @@ -138,143 +152,332 @@ export const ApplicationDetailsFooter = ({ [setIsOpenLogs], ); - const PlayerIcon = useMemo(() => { - switch (playerStatus) { - case SimpleApplicationStatus.DEPLOY: - return IconPlayerPlay; - case SimpleApplicationStatus.UNDEPLOY: - return IconPlaystationSquare; - case SimpleApplicationStatus.UPDATING: - default: - return Loader; - } - }, [playerStatus]); + const StatusIcons = { + [SimpleApplicationStatus.DEPLOY]: IconPlayerPlay, + [SimpleApplicationStatus.UNDEPLOY]: IconPlaystationSquare, + }; + const PlayerIcon = + playerStatus === SimpleApplicationStatus.UPDATING + ? Loader + : StatusIcons[playerStatus]; + const PlayerContextIcon = + playerStatus === SimpleApplicationStatus.UPDATING + ? LoaderIcon + : StatusIcons[playerStatus]; - const handleUpdateFunctionStatus = () => { + const handleUpdateFunctionStatus = useCallback(() => { dispatch( ApplicationActions.startUpdatingFunctionStatus({ id: entity.id, status: getApplicationNextStatus(entity), }), ); - }; + }, [dispatch, entity]); const handleOpenUnshare = useCallback( () => dispatch(ShareActions.setUnshareEntity(entity)), [dispatch, entity], ); + const handleOpenSharing = useCallback(() => { + dispatch( + ShareActions.share({ + featureType: FeatureType.Application, + resourceId: entity.id, + }), + ); + }, [dispatch, entity.id]); + const isApplicationsSharingEnabled = useAppSelector((state) => SettingsSelectors.isFeatureEnabled(state, Feature.ApplicationsSharing), ); + const link = useMemo( + () => + `${window.location.origin}/${PageType.Marketplace}?${MarketplaceQueryParams.model}=${entity.reference}`, + [entity.reference], + ); + + const handleCopy = useCallback(() => { + if (!navigator.clipboard) return; + navigator.clipboard.writeText(link); + dispatch(UIActions.showSuccessToast(t('Link copied!'))); + }, [dispatch, link, t]); + + const menuItems: DisplayMenuItemProps[] = useMemo( + () => [ + { + name: t('Copy link'), + dataQa: 'application-copy-link', + display: isPublicApp && isSmallScreen(), + Icon: IconLink, + onClick: (e: React.MouseEvent) => { + handleCopy(); + e.preventDefault(); + e.stopPropagation(); + }, + }, + { + name: t(getFunctionTooltip(entity)), + dataQa: 'application-status-toggler', + display: isExecutable && isCodeAppsEnabled, + disabled: playerStatus === SimpleApplicationStatus.UPDATING, + Icon: PlayerContextIcon, + iconClassName: classNames({ + ['text-error']: playerStatus === SimpleApplicationStatus.UNDEPLOY, + ['text-accent-secondary']: + playerStatus === SimpleApplicationStatus.DEPLOY, + ['animate-spin-steps']: + playerStatus === SimpleApplicationStatus.UPDATING, + }), + onClick: (e: React.MouseEvent) => { + e.stopPropagation(); + handleUpdateFunctionStatus(); + }, + }, + { + name: t('Share'), + dataQa: 'application-share', + display: isMyApp && isApplicationsSharingEnabled && isSmallScreen(), + Icon: IconUserShare, + onClick: (e: React.MouseEvent) => { + handleOpenSharing(); + e.stopPropagation(); + }, + }, + { + name: t('Unshare'), + dataQa: 'application-unshare', + display: !!entity.sharedWithMe && isApplicationsSharingEnabled, + Icon: IconUserUnshare, + onClick: (e: React.MouseEvent) => { + handleOpenUnshare(); + e.stopPropagation(); + }, + }, + { + name: t('Delete'), + dataQa: 'application-delete', + display: isMyApp, + disabled: isModifyDisabled, + Icon: IconTrashX, + onClick: (e: React.MouseEvent) => { + e.stopPropagation(); + onDelete?.(entity); + }, + }, + { + name: t('Publish'), + dataQa: 'publish', + display: isApplicationId(entity.id) && isMyApp, + Icon: IconWorldShare, + onClick: (e: React.MouseEvent) => { + e.stopPropagation(); + onPublish?.(entity, PublishActions.ADD); + }, + }, + { + name: t('Unpublish'), + dataQa: 'unpublish', + display: isApplicationId(entity.id) && isPublicEntity, + Icon: UnpublishIcon, + onClick: (e: React.MouseEvent) => { + e.stopPropagation(); + onPublish?.(entity, PublishActions.DELETE); + }, + }, + { + name: t('Edit'), + dataQa: 'edit', + display: (isMyApp || !!canWrite) && !!onEdit, + disabled: isAppInDeployment, + Icon: IconEdit, + onClick: (e: React.MouseEvent) => { + e.stopPropagation(); + onEdit?.(entity); + }, + }, + { + name: t('Application logs'), + dataQa: 'app-logs', + display: + isExecutable && playerStatus === SimpleApplicationStatus.UNDEPLOY, + Icon: IconFileDescription, + onClick: (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + handleLogClick(entity.id); + }, + }, + ], + [ + t, + isPublicApp, + entity, + isExecutable, + isCodeAppsEnabled, + playerStatus, + PlayerContextIcon, + isMyApp, + isApplicationsSharingEnabled, + isModifyDisabled, + isPublicEntity, + canWrite, + onEdit, + isAppInDeployment, + handleCopy, + handleUpdateFunctionStatus, + handleOpenSharing, + handleOpenUnshare, + onDelete, + onPublish, + handleLogClick, + ], + ); + + const hasBookmark = !isMyApp; + const countDisplayTrue = menuItems.filter((item) => item.display).length; + const menuItemsCount = hasBookmark ? countDisplayTrue + 1 : countDisplayTrue; + return (
-
- {isExecutable && isCodeAppsEnabled && ( - - - - )} - {!!entity.sharedWithMe && isApplicationsSharingEnabled && ( - - - - )} - {isMyApp ? ( - - - - ) : ( - - - - )} - - {isApplicationId(entity.id) && (isMyApp || isPublicApp) && ( - - - - )} - {(isMyApp || canWrite) && ( - - - - )} - {isExecutable && - playerStatus === SimpleApplicationStatus.UNDEPLOY && ( - + {isSmallScreen() && menuItemsCount > 2 ? ( + + ) : ( +
+ {isPublicApp && isSmallScreen() && ( + + )} + {isExecutable && isCodeAppsEnabled && ( + + + + )} + {isMyApp && isApplicationsSharingEnabled && isSmallScreen() && ( + )} -
+ {!!entity.sharedWithMe && isApplicationsSharingEnabled && ( + + + + )} + {isMyApp && ( + + + + )} + {isApplicationId(entity.id) && (isMyApp || isPublicEntity) && ( + + + + )} + {(isMyApp || canWrite) && ( + + + + )} + {isExecutable && + playerStatus === SimpleApplicationStatus.UNDEPLOY && ( + + + + )} +
+ )} + {hasBookmark && ( + + + + )}
{ const dispatch = useAppDispatch(); const screenState = useScreenState(); + const iconSize = + screenState === ScreenState.MOBILE ? SMALL_ICON_SIZE : DESKTOP_ICON_SIZE; + const shareIconSize = screenState === ScreenState.MOBILE - ? MOBILE_SHARE_ICON_SIZE + ? SMALL_SHARE_ICON_SIZE : DESKTOP_SHARE_ICON_SIZE; const isMyApp = isMyApplication(entity); @@ -104,7 +110,7 @@ export const ApplicationDetailsHeader = ({ entity }: Props) => { isCustomTooltip entity={entity} entityId={entity.id} - size={screenState === ScreenState.MOBILE ? 48 : 96} + size={iconSize} />
@@ -183,16 +189,20 @@ export const ApplicationDetailsHeader = ({ entity }: Props) => { */}
- {isMyApp && isApplicationsSharingEnabled && ( - + {isMyApp && + isApplicationsSharingEnabled && + screenState !== ScreenState.MOBILE && ( + + )} + {isPublicApp && screenState !== ScreenState.MOBILE && ( + )} - {isPublicApp && } ); }; diff --git a/apps/chat/src/components/Marketplace/CardsList.tsx b/apps/chat/src/components/Marketplace/CardsList.tsx index f6a3ee8ede..40e702e1fb 100644 --- a/apps/chat/src/components/Marketplace/CardsList.tsx +++ b/apps/chat/src/components/Marketplace/CardsList.tsx @@ -9,7 +9,6 @@ import { PublishActions } from '@epam/ai-dial-shared'; interface CardsListProps { entities: DialAIEntityModel[]; - isNotDesktop?: boolean; title?: string; className?: string; onCardClick: (entity: DialAIEntityModel) => void; @@ -22,7 +21,6 @@ interface CardsListProps { export const CardsList = ({ entities, - isNotDesktop, title, className, onCardClick, @@ -45,7 +43,6 @@ export const CardsList = ({ void; onPublish: (entity: DialAIEntityModel, action: PublishActions) => void; onDelete: (entity: DialAIEntityModel) => void; @@ -87,7 +85,6 @@ const ResultsView = ({ onPublish, onDelete, onEdit, - isNotDesktop, onBookmarkClick, }: ResultsViewProps) => { const { t } = useTranslation(Translation.Marketplace); @@ -108,7 +105,6 @@ const ResultsView = ({ onPublish={onPublish} onDelete={onDelete} onEdit={onEdit} - isNotDesktop={isNotDesktop} onBookmarkClick={onBookmarkClick} /> {!entities.length && ( @@ -134,7 +130,6 @@ const ResultsView = ({ onPublish={onPublish} onDelete={onDelete} onEdit={onEdit} - isNotDesktop={isNotDesktop} onBookmarkClick={onBookmarkClick} /> @@ -149,7 +144,6 @@ const ResultsView = ({ onPublish={onPublish} onDelete={onDelete} onEdit={onEdit} - isNotDesktop={isNotDesktop} onBookmarkClick={onBookmarkClick} /> ); @@ -208,11 +202,7 @@ const getDeleteConfirmationText = ( return deleteConfirmationText[action]; }; -interface TabRendererProps { - screenState: ScreenState; -} - -export const TabRenderer = ({ screenState }: TabRendererProps) => { +export const TabRenderer = () => { const { t } = useTranslation(Translation.Marketplace); const dispatch = useAppDispatch(); @@ -441,7 +431,6 @@ export const TabRenderer = ({ screenState }: TabRendererProps) => { onPublish={handleSetPublishEntity} onDelete={handleDelete} onEdit={handleEditApplication} - isNotDesktop={screenState !== ScreenState.DESKTOP} onBookmarkClick={handleBookmarkClick} /> From 1fdb66a788562f799a372cb0137466f441158f0c Mon Sep 17 00:00:00 2001 From: Derikyan Date: Mon, 27 Jan 2025 17:49:20 +0400 Subject: [PATCH 04/12] Merge branch 'development' of https://github.com/epam/ai-dial-chat into feat/2943-card-redesign From 2f16aae1829a69a47dcc0cfaf929a2a45cadbaa3 Mon Sep 17 00:00:00 2001 From: Derikyan Date: Mon, 27 Jan 2025 19:25:32 +0400 Subject: [PATCH 05/12] fix errors --- .../Marketplace/ApplicationDetails/ApplicationFooter.tsx | 8 ++++---- apps/chat/src/components/Marketplace/Marketplace.tsx | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx index 7caf59dae8..187d18a984 100644 --- a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx +++ b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx @@ -219,7 +219,7 @@ export const ApplicationDetailsFooter = ({ }, { name: t(getFunctionTooltip(entity)), - dataQa: 'application-status-toggler', + dataQa: 'status-change', display: isExecutable && isCodeAppsEnabled, disabled: playerStatus === SimpleApplicationStatus.UPDATING, Icon: PlayerContextIcon, @@ -237,7 +237,7 @@ export const ApplicationDetailsFooter = ({ }, { name: t('Share'), - dataQa: 'application-share', + dataQa: 'share', display: isMyApp && isApplicationsSharingEnabled && isSmallScreen(), Icon: IconUserShare, onClick: (e: React.MouseEvent) => { @@ -247,7 +247,7 @@ export const ApplicationDetailsFooter = ({ }, { name: t('Unshare'), - dataQa: 'application-unshare', + dataQa: 'unshare', display: !!entity.sharedWithMe && isApplicationsSharingEnabled, Icon: IconUserUnshare, onClick: (e: React.MouseEvent) => { @@ -257,7 +257,7 @@ export const ApplicationDetailsFooter = ({ }, { name: t('Delete'), - dataQa: 'application-delete', + dataQa: 'delete', display: isMyApp, disabled: isModifyDisabled, Icon: IconTrashX, diff --git a/apps/chat/src/components/Marketplace/Marketplace.tsx b/apps/chat/src/components/Marketplace/Marketplace.tsx index 468cef707c..610f50261e 100644 --- a/apps/chat/src/components/Marketplace/Marketplace.tsx +++ b/apps/chat/src/components/Marketplace/Marketplace.tsx @@ -59,8 +59,7 @@ export const Marketplace = () => {
) : ( <> - - + {showOverlay && } )} From f0e5ebdc444e66caf222a17152ef2010b348847e Mon Sep 17 00:00:00 2001 From: Derikyan Date: Tue, 28 Jan 2025 20:53:40 +0400 Subject: [PATCH 06/12] card version resizing --- .../components/Chat/ModelVersionSelect.tsx | 5 +- .../ApplicationDetails/ApplicationFooter.tsx | 262 +++++++++--------- 2 files changed, 137 insertions(+), 130 deletions(-) diff --git a/apps/chat/src/components/Chat/ModelVersionSelect.tsx b/apps/chat/src/components/Chat/ModelVersionSelect.tsx index b92ec3ec0a..7f94ea1108 100644 --- a/apps/chat/src/components/Chat/ModelVersionSelect.tsx +++ b/apps/chat/src/components/Chat/ModelVersionSelect.tsx @@ -82,7 +82,10 @@ export const ModelVersionSelect = ({ onClick={stopBubbling} > {showVersionPrefix && } - + {currentEntity.version || currentEntity.id} -
- {isSmallScreen() && menuItemsCount > 2 ? ( - - ) : ( -
- {isPublicApp && isSmallScreen() && ( - +
+ {isSmallScreen() && menuItemsCount > 2 ? ( + - - )} - {isMyApp && isApplicationsSharingEnabled && isSmallScreen() && ( - - - - )} - {!!entity.sharedWithMe && isApplicationsSharingEnabled && ( - - - - )} - {isMyApp && ( - - - - )} - {isApplicationId(entity.id) && (isMyApp || isPublicEntity) && ( - - - - )} - {(isMyApp || canWrite) && ( - - + ) : ( + <> + {isPublicApp && isSmallScreen() && ( + + )} + {isExecutable && isCodeAppsEnabled && ( + + + + )} + {isMyApp && isApplicationsSharingEnabled && isSmallScreen() && ( + + + + )} + {!!entity.sharedWithMe && isApplicationsSharingEnabled && ( + + + + )} + {isMyApp && ( + + + + )} + {isApplicationId(entity.id) && (isMyApp || isPublicEntity) && ( + - - - - )} - {isExecutable && - playerStatus === SimpleApplicationStatus.UNDEPLOY && ( - )} -
- )} - {hasBookmark && ( - - + + )} + {isExecutable && + playerStatus === SimpleApplicationStatus.UNDEPLOY && ( + + + + )} + + )} + {hasBookmark && ( + - - - - )} -
+ + + )} +
+
Date: Thu, 30 Jan 2025 18:17:24 +0400 Subject: [PATCH 07/12] fix conflicts --- .../src/components/Chat/TalkTo/TalkToCard.tsx | 26 ++-------- .../Marketplace/ApplicationCard.tsx | 26 ++-------- .../ApplicationCopyLink.tsx | 52 +++++++++---------- .../ApplicationDetails/ApplicationFooter.tsx | 21 +++++--- .../ApplicationDetails/ApplicationHeader.tsx | 16 ++---- apps/chat/src/constants/marketplace.ts | 19 ++++++- 6 files changed, 66 insertions(+), 94 deletions(-) diff --git a/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx b/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx index 5085fd292e..eaaefa741c 100644 --- a/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx +++ b/apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx @@ -31,7 +31,7 @@ import { SimpleApplicationStatus, } from '@/src/types/applications'; import { Conversation } from '@/src/types/chat'; -import { FeatureType, ScreenState } from '@/src/types/common'; +import { FeatureType } from '@/src/types/common'; import { DisplayMenuItemProps } from '@/src/types/menu'; import { DialAIEntityModel } from '@/src/types/models'; import { Translation } from '@/src/types/translation'; @@ -44,6 +44,7 @@ import { SettingsSelectors } from '@/src/store/settings/settings.reducers'; import { ShareActions } from '@/src/store/share/share.reducers'; import { REPLAY_AS_IS_MODEL } from '@/src/constants/chat'; +import { CardIconSizes } from '@/src/constants/marketplace'; import { ModelVersionSelect } from '@/src/components/Chat/ModelVersionSelect'; import { PlaybackIcon } from '@/src/components/Chat/Playback/PlaybackIcon'; @@ -60,14 +61,6 @@ import LoaderIcon from '@/public/images/icons/loader.svg'; import IconUserUnshare from '@/public/images/icons/unshare-user.svg'; import { Feature } from '@epam/ai-dial-shared'; -const DESKTOP_ICON_SIZE = 80; -const TABLET_ICON_SIZE = 48; -const MOBILE_ICON_SIZE = 40; - -const MOBILE_SHARE_ICON_SIZE = 16; -const TABLET_SHARE_ICON_SIZE = 20; -const DESKTOP_SHARE_ICON_SIZE = 30; - const getPlayerCaption = (entity: DialAIEntityModel) => { switch (entity.functionStatus) { case ApplicationStatus.DEPLOYED: @@ -135,6 +128,8 @@ export const TalkToCard = ({ SettingsSelectors.isFeatureEnabled(state, Feature.ApplicationsSharing), ); + const { iconSize, shareIconSize } = CardIconSizes[screenState]; + const versionsToSelect = useMemo(() => { return allModels.filter( (model) => @@ -307,23 +302,10 @@ export const TalkToCard = ({ ], ); - const iconSize = - screenState === ScreenState.DESKTOP - ? DESKTOP_ICON_SIZE - : screenState === ScreenState.TABLET - ? TABLET_ICON_SIZE - : MOBILE_ICON_SIZE; const isOldReplay = entity.id === REPLAY_AS_IS_MODEL && isOldConversationReplay(conversation.replay); - const shareIconSize = - screenState === ScreenState.MOBILE - ? MOBILE_SHARE_ICON_SIZE - : screenState === ScreenState.TABLET - ? TABLET_SHARE_ICON_SIZE - : DESKTOP_SHARE_ICON_SIZE; - return (
{ diff --git a/apps/chat/src/components/Marketplace/ApplicationCard.tsx b/apps/chat/src/components/Marketplace/ApplicationCard.tsx index 596f9197fa..e1b8e91390 100644 --- a/apps/chat/src/components/Marketplace/ApplicationCard.tsx +++ b/apps/chat/src/components/Marketplace/ApplicationCard.tsx @@ -31,7 +31,7 @@ import { ApplicationStatus, SimpleApplicationStatus, } from '@/src/types/applications'; -import { FeatureType, ScreenState } from '@/src/types/common'; +import { FeatureType } from '@/src/types/common'; import { DisplayMenuItemProps } from '@/src/types/menu'; import { DialAIEntityModel } from '@/src/types/models'; import { Translation } from '@/src/types/translation'; @@ -43,6 +43,8 @@ import { ModelsSelectors } from '@/src/store/models/models.reducers'; import { SettingsSelectors } from '@/src/store/settings/settings.reducers'; import { ShareActions } from '@/src/store/share/share.reducers'; +import { CardIconSizes } from '@/src/constants/marketplace'; + import { ModelIcon } from '@/src/components/Chatbar/ModelIcon'; import ContextMenu from '@/src/components/Common/ContextMenu'; import { EntityMarkdownDescription } from '@/src/components/Common/MarkdownDescription'; @@ -58,14 +60,6 @@ import UnpublishIcon from '@/public/images/icons/unpublish.svg'; import IconUserUnshare from '@/public/images/icons/unshare-user.svg'; import { Feature, PublishActions } from '@epam/ai-dial-shared'; -const MOBILE_ICON_SIZE = 40; -const TABLET_ICON_SIZE = 48; -const DESKTOP_ICON_SIZE = 80; - -const MOBILE_SHARE_ICON_SIZE = 16; -const TABLET_SHARE_ICON_SIZE = 20; -const DESKTOP_SHARE_ICON_SIZE = 30; - interface CardFooterProps { entity: DialAIEntityModel; } @@ -147,19 +141,7 @@ export const ApplicationCard = ({ const isExecutable = isExecutableApp(entity) && (isMyApp || isAdmin || canWrite); - const iconSize = - screenState === ScreenState.DESKTOP - ? DESKTOP_ICON_SIZE - : screenState === ScreenState.TABLET - ? TABLET_ICON_SIZE - : MOBILE_ICON_SIZE; - - const shareIconSize = - screenState === ScreenState.MOBILE - ? MOBILE_SHARE_ICON_SIZE - : screenState === ScreenState.TABLET - ? TABLET_SHARE_ICON_SIZE - : DESKTOP_SHARE_ICON_SIZE; + const { iconSize, shareIconSize } = CardIconSizes[screenState]; const PlayerIcon = useMemo(() => { switch (playerStatus) { diff --git a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx index 709602a650..566f8ab6d8 100644 --- a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx +++ b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationCopyLink.tsx @@ -1,10 +1,10 @@ import { IconCheck, IconLink } from '@tabler/icons-react'; import { MouseEvent, useCallback, useMemo, useRef, useState } from 'react'; -import { useTranslation } from '@/src/hooks/useTranslation'; - import classNames from 'classnames'; +import { useTranslation } from '@/src/hooks/useTranslation'; + import { PageType } from '@/src/types/common'; import { Translation } from '@/src/types/translation'; @@ -55,32 +55,28 @@ export function ApplicationCopyLink({ [link], ); - const Content = urlCopied ? ( -
- - {withText && {t('Copied!')}} -
- ) : ( - - - {withText && {t('Copy link')}} - - ); - return ( - <> - {hasTooltip ? ( - - {Content} - - ) : ( - Content - )} - + + <> + {urlCopied ? ( +
+ + {withText && {t('Copied!')}} +
+ ) : ( + + + {withText && {t('Copy link')}} + + )} + +
); } diff --git a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx index c153fc026c..9c00496f1b 100644 --- a/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx +++ b/apps/chat/src/components/Marketplace/ApplicationDetails/ApplicationFooter.tsx @@ -14,6 +14,7 @@ import { useCallback, useMemo, useState } from 'react'; import classNames from 'classnames'; +import { useScreenState } from '@/src/hooks/useScreenState'; import { useTranslation } from '@/src/hooks/useTranslation'; import { @@ -25,7 +26,6 @@ import { isExecutableApp, } from '@/src/utils/app/application'; import { isApplicationId, isMyApplication } from '@/src/utils/app/id'; -import { isSmallScreen } from '@/src/utils/app/mobile'; import { isEntityIdPublic } from '@/src/utils/app/publications'; import { canWriteSharedWithMe } from '@/src/utils/app/share'; @@ -33,7 +33,7 @@ import { ApplicationStatus, SimpleApplicationStatus, } from '@/src/types/applications'; -import { FeatureType, PageType } from '@/src/types/common'; +import { FeatureType, PageType, ScreenState } from '@/src/types/common'; import { DisplayMenuItemProps } from '@/src/types/menu'; import { DialAIEntityModel } from '@/src/types/models'; import { Translation } from '@/src/types/translation'; @@ -112,6 +112,8 @@ export const ApplicationDetailsFooter = ({ const { t } = useTranslation(Translation.Marketplace); const dispatch = useAppDispatch(); + const screenState = useScreenState(); + const [isOpenLogs, setIsOpenLogs] = useState(); const isCodeAppsEnabled = useAppSelector((state) => @@ -127,6 +129,8 @@ export const ApplicationDetailsFooter = ({ const isPublicEntity = isEntityIdPublic(entity); const isPublicApp = isApplicationPublic(entity); + const isSmallScreen = screenState === ScreenState.MOBILE; + const Bookmark = installedModelIds.has(entity.reference) ? IconBookmarkFilled : IconBookmark; @@ -209,7 +213,7 @@ export const ApplicationDetailsFooter = ({ { name: t('Copy link'), dataQa: 'application-copy-link', - display: isPublicApp && isSmallScreen(), + display: isPublicApp && isSmallScreen, Icon: IconLink, onClick: (e: React.MouseEvent) => { handleCopy(); @@ -238,7 +242,7 @@ export const ApplicationDetailsFooter = ({ { name: t('Share'), dataQa: 'share', - display: isMyApp && isApplicationsSharingEnabled && isSmallScreen(), + display: isMyApp && isApplicationsSharingEnabled && isSmallScreen, Icon: IconUserShare, onClick: (e: React.MouseEvent) => { handleOpenSharing(); @@ -313,6 +317,7 @@ export const ApplicationDetailsFooter = ({ [ t, isPublicApp, + isSmallScreen, entity, isExecutable, isCodeAppsEnabled, @@ -335,7 +340,7 @@ export const ApplicationDetailsFooter = ({ ], ); - const hasBookmark = !isMyApp; + const hasBookmark = !isMyApp || !entity.sharedWithMe; const countDisplayTrue = menuItems.filter((item) => item.display).length; const menuItemsCount = hasBookmark ? countDisplayTrue + 1 : countDisplayTrue; @@ -343,7 +348,7 @@ export const ApplicationDetailsFooter = ({
- {isSmallScreen() && menuItemsCount > 2 ? ( + {isSmallScreen && menuItemsCount > 2 ? ( )} - {isApplicationId(entity.id) && (isMyApp || isPublicEntity) && ( - + {(isMyApp || hasPublicId) && ( +