From e7bb9a2a651cf926edd4fef83cd9383b0b6831d5 Mon Sep 17 00:00:00 2001 From: harini-venkataraman <115449948+harini-venkataraman@users.noreply.github.com> Date: Wed, 24 Jul 2024 17:03:39 +0530 Subject: [PATCH] [FIX] Public share fixes (#513) * Fixing import issues * Public share fixes * Support for default profile APIs in Public share * Public share FE Fixes * Import fixes * Renaming methods * Removing console logs * Handing public share for PATCH calls --- .../output_manager_helper.py | 12 ++++- .../prompt_studio_output_manager/views.py | 2 +- .../combined-output/CombinedOutput.jsx | 8 +++- .../components/custom-tools/footer/Footer.jsx | 4 ++ .../manage-docs-modal/ManageDocsModal.jsx | 24 +++++++--- .../OutputAnalyzerCard.jsx | 18 +++++-- .../OutputAnalyzerHeader.jsx | 47 ++++++++++++------- .../OutputAnalyzerList.css | 6 +++ .../OutputAnalyzerList.jsx | 10 +++- .../OutputForDocModal.jsx | 5 +- .../custom-tools/prompt-card/PromptCard.jsx | 3 +- .../prompt-card/PromptCardItems.jsx | 5 +- .../custom-tools/tool-ide/ToolIde.css | 6 +++ .../custom-tools/tool-ide/ToolIde.jsx | 18 +++++-- 14 files changed, 127 insertions(+), 41 deletions(-) diff --git a/backend/prompt_studio/prompt_studio_output_manager/output_manager_helper.py b/backend/prompt_studio/prompt_studio_output_manager/output_manager_helper.py index 41cd5bbc7..c9b3672a8 100644 --- a/backend/prompt_studio/prompt_studio_output_manager/output_manager_helper.py +++ b/backend/prompt_studio/prompt_studio_output_manager/output_manager_helper.py @@ -147,9 +147,19 @@ def fetch_default_llm_profile(tool: CustomTool) -> ProfileManager: raise DefaultProfileError("Default ProfileManager does not exist.") @staticmethod - def fetch_default_response( + def fetch_default_output_response( tool_studio_prompts: list[ToolStudioPrompt], document_manager_id: str ) -> dict[str, Any]: + """Method to frame JSON responses for combined output for default for + default profile manager of the project. + + Args: + tool_studio_prompts (list[ToolStudioPrompt]) + document_manager_id (str) + + Returns: + dict[str, Any]: Formatted JSON response for combined output. + """ # Initialize the result dictionary result: dict[str, Any] = {} # Iterate over ToolStudioPrompt records diff --git a/backend/prompt_studio/prompt_studio_output_manager/views.py b/backend/prompt_studio/prompt_studio_output_manager/views.py index 7c64d6d20..3c38cd6ec 100644 --- a/backend/prompt_studio/prompt_studio_output_manager/views.py +++ b/backend/prompt_studio/prompt_studio_output_manager/views.py @@ -78,7 +78,7 @@ def get_output_for_tool_default(self, request: HttpRequest) -> Response: raise APIException(detail=tool_not_found, code=400) # Invoke helper method to frame and fetch default response. - result: dict[str, Any] = OutputManagerHelper.fetch_default_response( + result: dict[str, Any] = OutputManagerHelper.fetch_default_output_response( tool_studio_prompts=tool_studio_prompts, document_manager_id=document_manager_id, ) diff --git a/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx b/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx index 6d5028438..9e3ef8fea 100644 --- a/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx +++ b/frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx @@ -3,6 +3,7 @@ import "prismjs/plugins/line-numbers/prism-line-numbers.css"; import "prismjs/plugins/line-numbers/prism-line-numbers.js"; import "prismjs/themes/prism.css"; import { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; import PropTypes from "prop-types"; import { @@ -18,7 +19,6 @@ import { SpinnerLoader } from "../../widgets/spinner-loader/SpinnerLoader"; import "./CombinedOutput.css"; import { useExceptionHandler } from "../../../hooks/useExceptionHandler"; import { JsonView } from "./JsonView"; -import { useParams } from "react-router-dom"; let TableView; let promptOutputApiSps; @@ -32,11 +32,14 @@ try { } let publicOutputsDocApi; let publicAdapterApi; +let publicDefaultOutputApi; try { publicOutputsDocApi = require("../../../plugins/prompt-studio-public-share/helpers/PublicShareAPIs").publicOutputsDocApi; publicAdapterApi = require("../../../plugins/prompt-studio-public-share/helpers/PublicShareAPIs").publicAdapterApi; + publicDefaultOutputApi = + require("../../../plugins/prompt-studio-public-share/helpers/PublicShareAPIs").publicDefaultOutputApi; } catch { // The component will remain null of it is not available } @@ -149,6 +152,9 @@ function CombinedOutput({ docId, setFilledFields }) { selectedProfile || defaultLlmProfile, singlePassExtractMode ); + if (activeKey === "0") { + url = publicDefaultOutputApi(id, docId); + } } else { url = `/api/v1/unstract/${ sessionDetails?.orgId diff --git a/frontend/src/components/custom-tools/footer/Footer.jsx b/frontend/src/components/custom-tools/footer/Footer.jsx index 039b0ec08..3f224c650 100644 --- a/frontend/src/components/custom-tools/footer/Footer.jsx +++ b/frontend/src/components/custom-tools/footer/Footer.jsx @@ -5,8 +5,10 @@ import { PlusOutlined } from "@ant-design/icons"; import "./Footer.css"; import { FooterLayout } from "../footer-layout/FooterLayout"; import { promptType } from "../../../helpers/GetStaticData"; +import { useCustomToolStore } from "../../../store/custom-tool-store"; function Footer({ activeKey, addPromptInstance }) { + const { isPublicSource } = useCustomToolStore(); if (activeKey === "1") { return ( @@ -16,6 +18,7 @@ function Footer({ activeKey, addPromptInstance }) { type="link" icon={} onClick={() => addPromptInstance(promptType.notes)} + disabled={isPublicSource} > Notes @@ -25,6 +28,7 @@ function Footer({ activeKey, addPromptInstance }) { type="link" icon={} onClick={() => addPromptInstance(promptType.prompt)} + disabled={isPublicSource} > Prompt diff --git a/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx b/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx index 49ff09bbf..053a5fa78 100644 --- a/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx +++ b/frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx @@ -19,6 +19,7 @@ import { } from "antd"; import PropTypes from "prop-types"; import { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; import { useAxiosPrivate } from "../../../hooks/useAxiosPrivate"; import { useExceptionHandler } from "../../../hooks/useExceptionHandler"; @@ -41,6 +42,13 @@ try { // The component will remain null if it is not available } +let publicIndexApi = null; +try { + publicIndexApi = + require("../../../plugins/prompt-studio-public-share/helpers/PublicShareAPIs").publicIndexApi; +} catch { + // The component will remain null if it is not available +} const indexTypes = { raw: "RAW", summarize: "Summarize", @@ -63,6 +71,7 @@ function ManageDocsModal({ const [lastMessagesUpdate, setLastMessagesUpdate] = useState(""); const { sessionDetails } = useSessionStore(); const { setAlertDetails } = useAlertStore(); + const { id } = useParams(); const { selectedDoc, listOfDocs, @@ -138,7 +147,7 @@ function ManageDocsModal({ }, [defaultLlmProfile, details]); useEffect(() => { - if (!open || isPublicSource) { + if (!open) { return; } handleGetIndexStatus(rawLlmProfile, indexTypes.raw); @@ -243,10 +252,13 @@ function ManageDocsModal({ handleIndexStatus(indexType, []); return; } - + let url = `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/document-index/?profile_manager=${llmProfileId}`; + if (isPublicSource) { + url = publicIndexApi(id, llmProfileId); + } const requestOptions = { method: "GET", - url: `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/document-index/?profile_manager=${llmProfileId}`, + url, }; handleLoading(indexType, true); @@ -425,8 +437,7 @@ function ManageDocsModal({ disabled={ disableLlmOrDocChange?.length > 0 || isSinglePassExtractLoading || - indexDocs.includes(item?.document_id) || - isPublicSource + indexDocs.includes(item?.document_id) } /> ), @@ -592,7 +603,8 @@ function ManageDocsModal({ disabled={ !defaultLlmProfile || disableLlmOrDocChange?.length > 0 || - isSinglePassExtractLoading + isSinglePassExtractLoading || + isPublicSource } > Upload New File diff --git a/frontend/src/components/custom-tools/output-analyzer-card/OutputAnalyzerCard.jsx b/frontend/src/components/custom-tools/output-analyzer-card/OutputAnalyzerCard.jsx index eb4ceb132..949b775d2 100644 --- a/frontend/src/components/custom-tools/output-analyzer-card/OutputAnalyzerCard.jsx +++ b/frontend/src/components/custom-tools/output-analyzer-card/OutputAnalyzerCard.jsx @@ -11,26 +11,38 @@ import { useSessionStore } from "../../../store/session-store"; import { CombinedOutput } from "../combined-output/CombinedOutput"; import { DocumentViewer } from "../document-viewer/DocumentViewer"; import { PdfViewer } from "../pdf-viewer/PdfViewer"; +import { useParams } from "react-router-dom"; +let publicDocumentApi; +try { + publicDocumentApi = + require("../../../plugins/prompt-studio-public-share/helpers/PublicShareAPIs").publicDocumentApi; +} catch { + // The component will remain null of it is not available +} function OutputAnalyzerCard({ doc, totalFields }) { const [fileUrl, setFileUrl] = useState(""); const [isDocLoading, setIsDocLoading] = useState(false); const [filledFields, setFilledFields] = useState(0); - const { details } = useCustomToolStore(); + const { details, isPublicSource } = useCustomToolStore(); const { sessionDetails } = useSessionStore(); const { setAlertDetails } = useAlertStore(); const axiosPrivate = useAxiosPrivate(); const handleException = useExceptionHandler(); + const { id } = useParams(); useEffect(() => { if (!doc) { setFileUrl(""); return; } - + let url = `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/file/${details?.tool_id}?document_id=${doc?.document_id}`; + if (isPublicSource) { + url = publicDocumentApi(id, doc?.document_id, null); + } const requestOptions = { method: "GET", - url: `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/file/${details?.tool_id}?document_id=${doc?.document_id}`, + url, }; setIsDocLoading(true); diff --git a/frontend/src/components/custom-tools/output-analyzer-header/OutputAnalyzerHeader.jsx b/frontend/src/components/custom-tools/output-analyzer-header/OutputAnalyzerHeader.jsx index 310bb3252..7c847a297 100644 --- a/frontend/src/components/custom-tools/output-analyzer-header/OutputAnalyzerHeader.jsx +++ b/frontend/src/components/custom-tools/output-analyzer-header/OutputAnalyzerHeader.jsx @@ -3,29 +3,44 @@ import { ArrowLeftOutlined } from "@ant-design/icons"; import { useNavigate, useParams } from "react-router-dom"; import { useSessionStore } from "../../../store/session-store"; +import { useCustomToolStore } from "../../../store/custom-tool-store"; + +let HeaderPublic; +try { + HeaderPublic = + require("../../../plugins/prompt-studio-public-share/header-public/HeaderPublic.jsx").HeaderPublic; +} catch (err) { + // Do nothing if plugins are not loaded. +} function OutputAnalyzerHeader() { const { sessionDetails } = useSessionStore(); const { id } = useParams(); const navigate = useNavigate(); - + const { isPublicSource } = useCustomToolStore(); + const handleNavigate = () => { + if (isPublicSource) { + navigate(`/promptStudio/share/${id}`); + } else { + navigate(`/${sessionDetails?.orgName}/tools/${id}`); + } + }; return ( -
-
- - - - Output Analyzer - - +
+ {isPublicSource && HeaderPublic && } +
+
+ + + + Output Analyzer + + +
+
-
); } diff --git a/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.css b/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.css index 05d207d66..0c95db270 100644 --- a/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.css +++ b/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.css @@ -26,6 +26,12 @@ overflow-y: auto; } +.public-output-analyzer-body { + padding: 12px; + overflow-y: auto; + width:100vw; +} + .output-analyzer-body2 { height: 700px; display: flex; diff --git a/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.jsx b/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.jsx index 25555efe5..92b3083e1 100644 --- a/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.jsx +++ b/frontend/src/components/custom-tools/output-analyzer-list/OutputAnalyzerList.jsx @@ -8,7 +8,7 @@ import { promptType } from "../../../helpers/GetStaticData"; function OutputAnalyzerList() { const [totalFields, setTotalFields] = useState(0); - const { listOfDocs, details } = useCustomToolStore(); + const { listOfDocs, details, isPublicSource } = useCustomToolStore(); useEffect(() => { const prompts = [...(details?.prompts || [])]; @@ -23,7 +23,13 @@ function OutputAnalyzerList() {
-
+
{listOfDocs.map((doc) => { return (
diff --git a/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx b/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx index 50ee81cd7..f9dc4a857 100644 --- a/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx +++ b/frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx @@ -7,6 +7,7 @@ import { InfoCircleFilled, } from "@ant-design/icons"; import { useNavigate, useParams } from "react-router-dom"; +import TabPane from "antd/es/tabs/TabPane"; import { useCustomToolStore } from "../../../store/custom-tool-store"; import { useSessionStore } from "../../../store/session-store"; @@ -22,7 +23,6 @@ import { useAlertStore } from "../../../store/alert-store"; import { useExceptionHandler } from "../../../hooks/useExceptionHandler"; import { TokenUsage } from "../token-usage/TokenUsage"; import { useTokenUsageStore } from "../../../store/token-usage-store"; -import TabPane from "antd/es/tabs/TabPane"; import { ProfileInfoBar } from "../profile-info-bar/ProfileInfoBar"; let publicOutputsApi; @@ -191,7 +191,8 @@ function OutputForDocModal({ } let url = `/api/v1/unstract/${sessionDetails?.orgId}/prompt-studio/prompt-output/?tool_id=${details?.tool_id}&prompt_id=${promptId}&profile_manager=${profile}&is_single_pass_extract=${singlePassExtractMode}`; if (isPublicSource) { - url = publicOutputsApi(id, promptId, profile, singlePassExtractMode); + url = publicOutputsApi(id, promptId, singlePassExtractMode); + url += `&profile_manager=${profile}`; } const requestOptions = { method: "GET", diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx index 7e0e37585..35609066a 100644 --- a/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx +++ b/frontend/src/components/custom-tools/prompt-card/PromptCard.jsx @@ -1,5 +1,6 @@ import PropTypes from "prop-types"; import { useEffect, useState } from "react"; +import { useParams } from "react-router-dom"; import { defaultTokenUsage, @@ -18,7 +19,6 @@ import useTokenUsage from "../../../hooks/useTokenUsage"; import { useTokenUsageStore } from "../../../store/token-usage-store"; import { PromptCardItems } from "./PromptCardItems"; import "./PromptCard.css"; -import { useParams } from "react-router-dom"; const EvalModal = null; const getEvalMetrics = (param1, param2) => { @@ -703,7 +703,6 @@ function PromptCard({ url = publicOutputsApi( id, promptDetails?.prompt_id, - selectedLlmProfileId, singlePassExtractMode ); } diff --git a/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx b/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx index b8d147164..44a4cf9e1 100644 --- a/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx +++ b/frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx @@ -26,6 +26,8 @@ import { Typography, } from "antd"; import { useEffect, useRef, useState } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import CheckableTag from "antd/es/tag/CheckableTag"; import { displayPromptResult, @@ -36,8 +38,6 @@ import { EditableText } from "../editable-text/EditableText"; import { TokenUsage } from "../token-usage/TokenUsage"; import { useCustomToolStore } from "../../../store/custom-tool-store"; import { Header } from "./Header"; -import CheckableTag from "antd/es/tag/CheckableTag"; -import { motion, AnimatePresence } from "framer-motion"; import { OutputForIndex } from "./OutputForIndex"; import { useWindowDimensions } from "../../../hooks/useWindowDimensions"; @@ -313,7 +313,6 @@ function PromptCardItems({ type="link" className="display-flex-align-center prompt-card-action-button" onClick={() => setOpenOutputForDoc(true)} - disabled={isPublicSource} > {isCoverageLoading ? ( diff --git a/frontend/src/components/custom-tools/tool-ide/ToolIde.css b/frontend/src/components/custom-tools/tool-ide/ToolIde.css index e568d504b..d61f0fb80 100644 --- a/frontend/src/components/custom-tools/tool-ide/ToolIde.css +++ b/frontend/src/components/custom-tools/tool-ide/ToolIde.css @@ -102,3 +102,9 @@ .tool-ide-main-card .card-text { font-size: 12px; } + +.public-tool-ide-body{ + flex: 1 1; + overflow-y: hidden; + width: 100vw; +} diff --git a/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx b/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx index 0dfaae6fd..f0d9110db 100644 --- a/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx +++ b/frontend/src/components/custom-tools/tool-ide/ToolIde.jsx @@ -91,6 +91,13 @@ function ToolIde() { } }, [shareId, openShareModal]); + useEffect(() => { + if (!openShareModal) { + setOpenShareConfirmation(false); + setOpenShareLink(false); + } + }, [openShareModal]); + const genExtra = () => ( { @@ -202,11 +209,12 @@ function ToolIde() { selectedDoc: doc, }; updateCustomTool(data); - + if (isPublicSource) { + return; + } const body = { output: doc?.document_id, }; - handleUpdateTool(body).catch((err) => { const revertSelectedDoc = { selectedDoc: prevSelectedDoc, @@ -227,7 +235,9 @@ function ToolIde() { setOpenCloneModal={setOpenCloneModal} />
-
+
@@ -299,7 +309,7 @@ function ToolIde() { setOpenCloneModal={setOpenCloneModal} /> )} - {!promptOnboardingMessage && OnboardMessagesModal && ( + {!promptOnboardingMessage && OnboardMessagesModal && !isPublicSource && (