Skip to content

Commit

Permalink
feat(chat): Add share icon in applications, sources filters (Issue #2915
Browse files Browse the repository at this point in the history
) (#2945)
  • Loading branch information
Derikyan authored Jan 22, 2025
1 parent 738366f commit 49077cb
Show file tree
Hide file tree
Showing 20 changed files with 342 additions and 152 deletions.
2 changes: 1 addition & 1 deletion apps/chat/public/images/icons/arrow-up-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions apps/chat/src/components/Chat/MainModalManager.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ReplaceConfirmationModal } from '../Common/ReplaceConfirmationModal/ReplaceConfirmationModal';
import { UnshareDialog } from '../Common/UnshareDialog';
import { RenameConversationModal } from './RenameConversationModal';
import ShareModal from './ShareModal';

export const MainModalManager = () => {
return (
<>
<ShareModal />
<UnshareDialog />
<ReplaceConfirmationModal />
<RenameConversationModal />
</>
Expand Down
144 changes: 92 additions & 52 deletions apps/chat/src/components/Chat/ShareModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import { ModalState } from '@/src/types/modal';
import { Translation } from '@/src/types/translation';

import { useAppDispatch, useAppSelector } from '@/src/store/hooks';
import { ModelsSelectors } from '@/src/store/models/models.reducers';
import { ShareActions, ShareSelectors } from '@/src/store/share/share.reducers';

import { OUTSIDE_PRESS_AND_MOUSE_EVENT } from '@/src/constants/modal';

import Modal from '../Common/Modal';
import Tooltip from '../Common/Tooltip';

import IconUserUnshare from '@/public/images/icons/unshare-user.svg';
import { SharePermission } from '@epam/ai-dial-shared';

export const ShareModal = () => {
Expand Down Expand Up @@ -88,12 +90,15 @@ export default function ShareModalView() {
const shareResourceName = useAppSelector(
ShareSelectors.selectShareResourceName,
);
const shareResourceVersion = useAppSelector(
ShareSelectors.selectShareResourceVersion,
);

const shareFeatureType = useAppSelector(
ShareSelectors.selectShareFeatureType,
);

const entity = useAppSelector((state) =>
ModelsSelectors.selectModelById(state, shareResourceId),
);

const isFolder = useAppSelector(ShareSelectors.selectShareIsFolder);

const sharingType = useMemo(() => {
Expand Down Expand Up @@ -155,68 +160,103 @@ export default function ShareModalView() {
[url],
);

const handleOpenUnshare = useCallback(() => {
handleClose();
dispatch(ShareActions.setUnshareEntity(entity));
}, [dispatch, entity, handleClose]);

useEffect(() => () => clearTimeout(timeoutRef.current), []);
return (
<Modal
portalId="theme-main"
containerClassName="inline-block w-full max-w-[424px] px-3 py-4 md:p-6"
containerClassName="inline-block w-full max-w-[424px]"
dataQa="share-modal"
state={modalState}
onClose={handleClose}
heading={`${t('Share')}: ${shareResourceName?.trim()}`}
dismissProps={OUTSIDE_PRESS_AND_MOUSE_EVENT}
>
<div className="flex flex-col justify-between gap-2">
{shareResourceVersion && <span>Version: {shareResourceVersion}</span>}
<p className="text-sm text-secondary">
{t('share.modal.link.description')}
</p>
<p className="text-sm text-secondary">
{t('share.modal.link', { context: sharingType })}
</p>
{shareFeatureType === FeatureType.Application && (
<div className="my-2 flex flex-col gap-2">
<ShareAccessOption
filterValue="Allow editing by other users"
selected={editAccess}
onSelect={onChangeSharePermissionHandler}
/>
</div>
)}
<div className="relative mt-2">
<Tooltip tooltip={url}>
<input
type="text"
readOnly
className="w-full gap-2 truncate rounded border border-primary bg-layer-3 p-3 pr-10 outline-none"
onCopyCapture={handleCopy}
value={url}
data-qa="share-link"
/>
<div className="px-3 py-4 md:p-6">
<h4 className="mb-2 max-h-[50px] whitespace-pre-wrap text-left text-base font-semibold">
<Tooltip
contentClassName="max-w-[400px] break-words"
tooltip={t(`${t('Share')}: ${shareResourceName?.trim()}`)}
>
<div
className="line-clamp-2 w-full break-words"
data-qa="modal-entity-name"
>
{t(`${t('Share')}: ${shareResourceName?.trim()}`)}
</div>
</Tooltip>
<div className="absolute right-3 top-3">
{urlCopied ? (
<Tooltip tooltip={t('Copied!')}>
<IconCheck size={20} className="text-secondary" />
</Tooltip>
) : (
<Tooltip tooltip={t('Copy URL')}>
<button
className="outline-none"
onClick={handleCopy}
data-qa="copy-link"
>
<IconCopy
height={20}
width={20}
className="text-secondary hover:text-accent-primary"
/>
</button>
</Tooltip>
)}
</h4>

<div className="flex flex-col justify-between gap-2">
{entity?.version && <span>Version: {entity.version}</span>}
<p className="text-sm text-secondary">
{t('share.modal.link.description')}
</p>
<p className="text-sm text-secondary">
{t('share.modal.link', { context: sharingType })}
</p>
{shareFeatureType === FeatureType.Application && (
<div className="my-2 flex flex-col gap-2">
<ShareAccessOption
filterValue="Allow editing by other users"
selected={editAccess}
onSelect={onChangeSharePermissionHandler}
/>
</div>
)}
<div className="relative mt-2">
<Tooltip tooltip={url}>
<input
type="text"
readOnly
className="w-full gap-2 truncate rounded border border-primary bg-layer-3 p-3 pr-10 outline-none"
onCopyCapture={handleCopy}
value={url}
data-qa="share-link"
/>
</Tooltip>
<div className="absolute right-3 top-3">
{urlCopied ? (
<Tooltip tooltip={t('Copied!')}>
<IconCheck size={20} className="text-secondary" />
</Tooltip>
) : (
<Tooltip tooltip={t('Copy URL')}>
<button
className="outline-none"
onClick={handleCopy}
data-qa="copy-link"
>
<IconCopy
height={20}
width={20}
className="text-secondary hover:text-accent-primary"
/>
</button>
</Tooltip>
)}
</div>
</div>
</div>
</div>
{shareFeatureType === FeatureType.Application && (
<div className="divide-y-0 border-t border-tertiary px-3 py-4 text-sm text-secondary md:p-6">
{entity?.isShared ? (
<button
onClick={handleOpenUnshare}
className="flex gap-2 text-sm text-accent-primary"
>
<IconUserUnshare height={18} width={18} />
<p>{t('Remove access for all users')}</p>
</button>
) : (
<p>{t('This app has not been shared with anyone yet.')}</p>
)}
</div>
)}
</Modal>
);
}
49 changes: 36 additions & 13 deletions apps/chat/src/components/Chat/TalkTo/TalkToCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
IconUserShare,
IconWorldShare,
} from '@tabler/icons-react';
import React, { useCallback, useMemo, useState } from 'react';
import React, { useCallback, useMemo } from 'react';

import { useTranslation } from 'next-i18next';

Expand Down Expand Up @@ -55,7 +55,7 @@ import { EntityMarkdownDescription } from '@/src/components/Common/MarkdownDescr
import { ApplicationTopic } from '@/src/components/Marketplace/ApplicationTopic';
import { FunctionStatusIndicator } from '@/src/components/Marketplace/FunctionStatusIndicator';

import UnshareDialog from '../../Common/UnshareDialog';
import ShareIcon from '../../Common/ShareIcon';

import LoaderIcon from '@/public/images/icons/loader.svg';
import IconUserUnshare from '@/public/images/icons/unshare-user.svg';
Expand All @@ -65,6 +65,10 @@ 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:
Expand Down Expand Up @@ -111,8 +115,6 @@ export const TalkToCard = ({

const dispatch = useAppDispatch();

const [isUnshareConfirmOpened, setIsUnshareConfirmOpened] = useState(false);

const installedModelIds = useAppSelector(
ModelsSelectors.selectInstalledModelIds,
);
Expand Down Expand Up @@ -193,6 +195,11 @@ export const TalkToCard = ({
);
}, [dispatch, entity.id]);

const handleOpenUnshare = useCallback(
() => dispatch(ShareActions.setUnshareEntity(entity)),
[dispatch, entity],
);

const menuItems: DisplayMenuItemProps[] = useMemo(
() => [
{
Expand Down Expand Up @@ -239,12 +246,10 @@ export const TalkToCard = ({
{
name: t('Unshare'),
dataQa: 'unshare',
display:
(!!entity.sharedWithMe || !!entity.isShared) &&
isApplicationsSharingEnabled,
display: !!entity.sharedWithMe && isApplicationsSharingEnabled,
Icon: IconUserUnshare,
onClick: (e: React.MouseEvent) => {
setIsUnshareConfirmOpened(true);
handleOpenUnshare();
e.stopPropagation();
},
},
Expand Down Expand Up @@ -291,15 +296,16 @@ export const TalkToCard = ({
isMyEntity,
isCodeAppsEnabled,
PlayerIcon,
onEdit,
canWrite,
onEdit,
isApplicationsSharingEnabled,
onPublish,
isExecutable,
onDelete,
isModifyDisabled,
handleUpdateFunctionStatus,
handleOpenSharing,
handleOpenUnshare,
onOpenLogs,
],
);
Expand All @@ -314,6 +320,13 @@ export const TalkToCard = ({
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 (
<div
onClick={() => {
Expand Down Expand Up @@ -359,7 +372,20 @@ export const TalkToCard = ({
)}
{!isPseudoModel(entity.reference) &&
entity.reference !== REPLAY_AS_IS_MODEL && (
<ModelIcon entityId={entity.id} entity={entity} size={iconSize} />
<ShareIcon
{...entity}
isHighlighted={false}
size={shareIconSize}
featureType={FeatureType.Application}
iconClassName="bg-layer-2 !stroke-[0.6] group-hover:bg-transparent !rounded-[4px]"
iconWrapperClassName="!rounded-[4px]"
>
<ModelIcon
entityId={entity.id}
entity={entity}
size={iconSize}
/>
</ShareIcon>
)}
</div>
<div className="flex grow flex-col justify-center gap-2 overflow-hidden leading-4">
Expand Down Expand Up @@ -428,9 +454,6 @@ export const TalkToCard = ({
))}
</div>
</div>
{isUnshareConfirmOpened && (
<UnshareDialog entity={entity} setOpened={setIsUnshareConfirmOpened} />
)}
</div>
);
};
2 changes: 1 addition & 1 deletion apps/chat/src/components/Common/ShareIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export default function ShareIcon({
width={size}
height={size}
className={classNames(
'stroke-1 p-px text-accent-primary group-hover:bg-accent-primary-alpha',
'stroke-[1.5] p-px text-accent-primary group-hover:bg-accent-primary-alpha',
isHighlighted && 'bg-accent-primary-alpha',
isPublished ? 'rounded-md' : 'rounded-sm',
iconClassName,
Expand Down
Loading

0 comments on commit 49077cb

Please sign in to comment.