diff --git a/apps/chat-e2e/src/testData/expectedConstants.ts b/apps/chat-e2e/src/testData/expectedConstants.ts
index 27fb72a3fd..f10b0b40a3 100644
--- a/apps/chat-e2e/src/testData/expectedConstants.ts
+++ b/apps/chat-e2e/src/testData/expectedConstants.ts
@@ -119,6 +119,8 @@ export const ExpectedConstants = {
'This link is temporary and will be active for 3 days. This conversation and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming or changing the model will stop sharing.',
sharePromptText:
'This link is temporary and will be active for 3 days. This prompt and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming will stop sharing.',
+ shareApplicationText:
+ 'This application and its updates will be visible to users with the link. Renaming or changing the version will stop sharing.',
shareConversationFolderText:
'This link is temporary and will be active for 3 days. This conversation folder and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming will stop sharing.',
sharePromptFolderText:
diff --git a/apps/chat/.env.development b/apps/chat/.env.development
index 2bbc5dc70e..f5df3acc67 100644
--- a/apps/chat/.env.development
+++ b/apps/chat/.env.development
@@ -91,7 +91,7 @@ DIAL_ROLES_FIELD="dial_roles"
# Application UI settings
-ENABLED_FEATURES="conversations-section,prompts-section,top-settings,top-clear-conversation,top-chat-info,top-chat-model-settings,empty-chat-settings,header,footer,request-api-key,report-an-issue,likes,conversations-sharing,prompts-sharing,input-files,attachments-manager,conversations-publishing,prompts-publishing,custom-logo,input-links,custom-applications,message-templates,marketplace,quick-apps,code-apps"
+ENABLED_FEATURES="conversations-section,prompts-section,top-settings,top-clear-conversation,top-chat-info,top-chat-model-settings,empty-chat-settings,header,footer,request-api-key,report-an-issue,likes,conversations-sharing,prompts-sharing,input-files,attachments-manager,conversations-publishing,prompts-publishing,custom-logo,input-links,custom-applications,message-templates,marketplace,quick-apps,code-apps,applications-sharing"
NEXT_PUBLIC_APP_NAME="Local Development APP Name"
NEXT_PUBLIC_DEFAULT_SYSTEM_PROMPT=""
NEXT_PUBLIC_DEFAULT_TEMPERATURE="1"
diff --git a/apps/chat/public/images/icons/unshare-user.svg b/apps/chat/public/images/icons/unshare-user.svg
new file mode 100644
index 0000000000..67904362f9
--- /dev/null
+++ b/apps/chat/public/images/icons/unshare-user.svg
@@ -0,0 +1,3 @@
+
diff --git a/apps/chat/public/locales/en/sidebar.json b/apps/chat/public/locales/en/sidebar.json
index 02d05d0ce1..609a54a8aa 100644
--- a/apps/chat/public/locales/en/sidebar.json
+++ b/apps/chat/public/locales/en/sidebar.json
@@ -3,5 +3,6 @@
"share.modal.link_conversation": "This conversation and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming or changing the model will stop sharing.",
"share.modal.link_prompt": "This prompt and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming will stop sharing.",
"share.modal.link_conversations_folder": "This conversation folder and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming will stop sharing.",
- "share.modal.link_prompts_folder": "This prompt folder and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming will stop sharing."
+ "share.modal.link_prompts_folder": "This prompt folder and future changes to it will be visible to users who follow the link. Only owner will be able to make changes. Renaming will stop sharing.",
+ "share.modal.link_application": "This application and its updates will be visible to users with the link. Renaming or changing the version will stop sharing."
}
diff --git a/apps/chat/src/components/Chat/ShareModal.tsx b/apps/chat/src/components/Chat/ShareModal.tsx
index d521bb23d7..82f3b8194b 100644
--- a/apps/chat/src/components/Chat/ShareModal.tsx
+++ b/apps/chat/src/components/Chat/ShareModal.tsx
@@ -13,6 +13,7 @@ import { useTranslation } from 'next-i18next';
import { getShareType } from '@/src/utils/app/share';
+import { FeatureType } from '@/src/types/common';
import { ModalState } from '@/src/types/modal';
import { Translation } from '@/src/types/translation';
@@ -24,6 +25,8 @@ import { OUTSIDE_PRESS_AND_MOUSE_EVENT } from '@/src/constants/modal';
import Modal from '../Common/Modal';
import Tooltip from '../Common/Tooltip';
+import { SharePermission } from '@epam/ai-dial-shared';
+
export const ShareModal = () => {
const isShareModalClosed = useAppSelector(
ShareSelectors.selectShareModalClosed,
@@ -33,6 +36,37 @@ export const ShareModal = () => {
}
};
+interface ShareAccessOptionProps {
+ filterValue: string;
+ selected: boolean;
+ onSelect: (value: boolean) => void;
+}
+
+const ShareAccessOption = ({
+ filterValue,
+ selected,
+ onSelect,
+}: ShareAccessOptionProps) => {
+ return (
+
+ );
+};
+
export default function ShareModalView() {
const { t } = useTranslation(Translation.SideBar);
const dispatch = useAppDispatch();
@@ -42,11 +76,22 @@ export default function ShareModalView() {
const [urlWasCopied, setUrlWasCopied] = useState(false);
const timeoutRef = useRef>();
+ const [editAccess, setEditAccess] = useState(false);
const modalState = useAppSelector(ShareSelectors.selectShareModalState);
- const invitationId = useAppSelector(ShareSelectors.selectInvitationId);
+ const readInvitationId = useAppSelector(ShareSelectors.selectInvitationId);
+ const writeInvitationId = useAppSelector(
+ ShareSelectors.selectWriteInvitationId,
+ );
+ const invitationId = editAccess ? writeInvitationId : readInvitationId;
+
+ const shareResourceId = useAppSelector(ShareSelectors.selectShareResourceId);
+
const shareResourceName = useAppSelector(
ShareSelectors.selectShareResourceName,
);
+ const shareResourceVersion = useAppSelector(
+ ShareSelectors.selectShareResourceVersion,
+ );
const shareFeatureType = useAppSelector(
ShareSelectors.selectShareFeatureType,
);
@@ -57,6 +102,26 @@ export default function ShareModalView() {
}, [shareFeatureType, isFolder]);
const [url, setUrl] = useState('');
+ const onChangeSharePermissionHandler = useCallback(
+ (isWrite: boolean) => {
+ setEditAccess(isWrite);
+ const shouldGetNewInvitationId =
+ (isWrite && !writeInvitationId) || (!isWrite && !readInvitationId);
+
+ if (shareResourceId && shouldGetNewInvitationId) {
+ dispatch(
+ ShareActions.shareApplication({
+ resourceId: shareResourceId,
+ permissions: isWrite
+ ? [SharePermission.READ, SharePermission.WRITE]
+ : [SharePermission.READ],
+ }),
+ );
+ }
+ },
+ [dispatch, readInvitationId, shareResourceId, writeInvitationId],
+ );
+
useEffect(() => {
setUrl(`${window?.location.origin}/share/${invitationId || ''}`);
}, [invitationId]);
@@ -86,7 +151,6 @@ export default function ShareModalView() {
);
useEffect(() => () => clearTimeout(timeoutRef.current), []);
-
return (