From 7375cc717c29ff6cf113ec42341042c3377a00b2 Mon Sep 17 00:00:00 2001 From: Predrag Klepic <60631598+Klepic95@users.noreply.github.com> Date: Mon, 17 Jul 2023 20:10:41 +0200 Subject: [PATCH] [Query Copilot] Scrollable Copilot tab, improved history and minor fixes (#1536) Co-authored-by: Predrag Klepic --- src/Explorer/QueryCopilot/QueryCopilotTab.tsx | 569 +++++++++--------- .../QueryCopilotTab.test.tsx.snap | 243 ++++---- 2 files changed, 420 insertions(+), 392 deletions(-) diff --git a/src/Explorer/QueryCopilot/QueryCopilotTab.tsx b/src/Explorer/QueryCopilot/QueryCopilotTab.tsx index 9a4bf9588..8420747aa 100644 --- a/src/Explorer/QueryCopilot/QueryCopilotTab.tsx +++ b/src/Explorer/QueryCopilot/QueryCopilotTab.tsx @@ -44,7 +44,6 @@ import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg"; import HintIcon from "../../../images/Hint.svg"; import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg"; import RecentIcon from "../../../images/Recent.svg"; -import SamplePromptsIcon from "../../../images/SamplePromptsIcon.svg"; import XErrorMessage from "../../../images/X-errorMessage.svg"; import SaveQueryIcon from "../../../images/save-cosmos.svg"; import { useTabs } from "../../hooks/useTabs"; @@ -122,12 +121,12 @@ export const QueryCopilotTab: React.FC = ({ }; const cachedHistoriesString = localStorage.getItem(`${userContext.databaseAccount?.id}-queryCopilotHistories`); - const cachedHistories = cachedHistoriesString?.split(","); + const cachedHistories = cachedHistoriesString?.split("|"); const [histories, setHistories] = useState(cachedHistories || []); const suggestedPrompts: SuggestedPrompt[] = [ - { id: 1, text: "Give me all customers whose names start with C" }, - { id: 2, text: "Show me all customers" }, - { id: 3, text: "Show me all customers who bought a bike in 2019" }, + { id: 1, text: 'Show all products that have the word "ultra" in the name or description' }, + { id: 2, text: "What are all of the possible categories for the products, and their counts?" }, + { id: 3, text: 'Show me all products that have been reviewed by someone with a username that contains "bob"' }, ]; const [filteredHistories, setFilteredHistories] = useState(histories); const [filteredSuggestedPrompts, setFilteredSuggestedPrompts] = useState(suggestedPrompts); @@ -149,9 +148,16 @@ export const QueryCopilotTab: React.FC = ({ }; const updateHistories = (): void => { - const newHistories = histories.length < 3 ? [userPrompt, ...histories] : [userPrompt, histories[1], histories[2]]; + const formattedUserPrompt = userPrompt.replace(/\s+/g, " ").trim(); + const existingHistories = histories.map((history) => history.replace(/\s+/g, " ").trim()); + + const updatedHistories = existingHistories.filter( + (history) => history.toLowerCase() !== formattedUserPrompt.toLowerCase() + ); + const newHistories = [formattedUserPrompt, ...updatedHistories.slice(0, 2)]; + setHistories(newHistories); - localStorage.setItem(`${userContext.databaseAccount.id}-queryCopilotHistories`, newHistories.join(",")); + localStorage.setItem(`${userContext.databaseAccount.id}-queryCopilotHistories`, newHistories.join("|")); }; const generateSQLQuery = async (): Promise => { @@ -260,16 +266,17 @@ export const QueryCopilotTab: React.FC = ({ disabled: query?.trim() === "", }; - const samplePromptsBtn = { - iconSrc: SamplePromptsIcon, - iconAlt: "Sample Prompts", - onCommandClick: () => setIsSamplePromptsOpen(true), - commandButtonLabel: "Sample Prompts", - ariaLabel: "Sample Prompts", - hasPopup: false, - }; + // Sample Prompts temporary disabled due current design + // const samplePromptsBtn = { + // iconSrc: SamplePromptsIcon, + // iconAlt: "Sample Prompts", + // onCommandClick: () => setIsSamplePromptsOpen(true), + // commandButtonLabel: "Sample Prompts", + // ariaLabel: "Sample Prompts", + // hasPopup: false, + // }; - return [executeQueryBtn, saveQueryBtn, samplePromptsBtn]; + return [executeQueryBtn, saveQueryBtn]; }; const showTeachingBubble = (): void => { if (!inputEdited.current) { @@ -301,277 +308,283 @@ export const QueryCopilotTab: React.FC = ({ }, []); return ( - - - - Copilot - - - { - inputEdited.current = true; - setShowSamplePrompts(true); - }} - style={{ lineHeight: 30 }} - styles={{ root: { width: "95%" } }} - disabled={isGeneratingQuery} - autoComplete="off" - /> - {copilotTeachingBubbleVisible && ( - - Write a prompt here and Copilot will generate the query for you. You can also choose from our{" "} - { - setShowSamplePrompts(true); - toggleCopilotTeachingBubbleVisible(); - }} - style={{ color: "white", fontWeight: 600 }} + +
+ + + Copilot + + + { + inputEdited.current = true; + setShowSamplePrompts(true); + }} + style={{ lineHeight: 30 }} + styles={{ root: { width: "95%" } }} + disabled={isGeneratingQuery} + autoComplete="off" + /> + {copilotTeachingBubbleVisible && ( + - sample prompts - {" "} - or write your own query - - )} - { - updateHistories(); - generateSQLQuery(); - resetButtonState(); - }} - /> - {isGeneratingQuery && } - {showSamplePrompts && ( - setShowSamplePrompts(false)} - directionalHintFixed={true} - directionalHint={DirectionalHint.bottomLeftEdge} - alignTargetEdge={true} - gapSpace={4} - > - - {filteredHistories?.length > 0 && ( - - - Recent - - {filteredHistories.map((history, i) => ( - { - setUserPrompt(history); - setShowSamplePrompts(false); - }} - onRenderIcon={() => } - styles={promptStyles} - > - {history} - - ))} - - )} - {filteredSuggestedPrompts?.length > 0 && ( - - - Suggested Prompts - - {filteredSuggestedPrompts.map((prompt) => ( - { - setUserPrompt(prompt.text); - setShowSamplePrompts(false); - }} - onRenderIcon={() => } - styles={promptStyles} - > - {prompt.text} - - ))} - - )} - {(filteredHistories?.length > 0 || filteredSuggestedPrompts?.length > 0) && ( - - - - Learn about{" "} - - writing effective prompts - - - - )} - - - )} - - - - AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.{" "} - - Read preview terms - - {showErrorMessageBar && ( - - - - We ran into an error and were not able to execute query. Please try again after sometime - - - )} - - - {showFeedbackBar && ( - - Provide feedback on the query generated - {showCallout && !hideFeedbackModalForLikedQueries && ( - { - setShowCallout(false); - submitFeedback({ generatedQuery, likeQuery, description: "", userPrompt: userPrompt }); - }} - directionalHint={DirectionalHint.topCenter} - > - - Thank you. Need to give{" "} - { - setShowCallout(false); - useQueryCopilot.getState().openFeedbackModal(generatedQuery, true, userPrompt); - }} - > - more feedback? - - - + Write a prompt here and Copilot will generate the query for you. You can also choose from our{" "} + { + setShowSamplePrompts(true); + toggleCopilotTeachingBubbleVisible(); + }} + style={{ color: "white", fontWeight: 600 }} + > + sample prompts + {" "} + or write your own query + )} { - setShowCallout(!likeQuery); - setLikeQuery(!likeQuery); - if (dislikeQuery) { - setDislikeQuery(!dislikeQuery); - } + updateHistories(); + generateSQLQuery(); + resetButtonState(); }} /> - { - if (!dislikeQuery) { - useQueryCopilot.getState().openFeedbackModal(generatedQuery, false, userPrompt); - setLikeQuery(false); - } - setDislikeQuery(!dislikeQuery); - setShowCallout(false); - }} - /> - - - Copy code - - { - setShowDeletePopup(true); - }} - iconProps={{ iconName: "Delete" }} - style={{ margin: "0 10px", backgroundColor: "#FFF8F0", transition: "background-color 0.3s ease" }} - > - Delete code - + {isGeneratingQuery && } + {showSamplePrompts && ( + setShowSamplePrompts(false)} + directionalHintFixed={true} + directionalHint={DirectionalHint.bottomLeftEdge} + alignTargetEdge={true} + gapSpace={4} + > + + {filteredHistories?.length > 0 && ( + + + Recent + + {filteredHistories.map((history, i) => ( + { + setUserPrompt(history); + setShowSamplePrompts(false); + }} + onRenderIcon={() => } + styles={promptStyles} + > + {history} + + ))} + + )} + {filteredSuggestedPrompts?.length > 0 && ( + + + Suggested Prompts + + {filteredSuggestedPrompts.map((prompt) => ( + { + setUserPrompt(prompt.text); + setShowSamplePrompts(false); + }} + onRenderIcon={() => } + styles={promptStyles} + > + {prompt.text} + + ))} + + )} + {(filteredHistories?.length > 0 || filteredSuggestedPrompts?.length > 0) && ( + + + + Learn about{" "} + + writing effective prompts + + + + )} + + + )} - )} - - - setQuery(newQuery)} - onContentSelected={(selectedQuery: string) => setSelectedQuery(selectedQuery)} + + + AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.{" "} + + Read preview terms + + {showErrorMessageBar && ( + + + + We ran into an error and were not able to execute query. Please try again after sometime + + + )} + + + + {showFeedbackBar && ( + + Provide feedback on the query generated + {showCallout && !hideFeedbackModalForLikedQueries && ( + { + setShowCallout(false); + submitFeedback({ generatedQuery, likeQuery, description: "", userPrompt: userPrompt }); + }} + directionalHint={DirectionalHint.topCenter} + > + + Thank you. Need to give{" "} + { + setShowCallout(false); + useQueryCopilot.getState().openFeedbackModal(generatedQuery, true, userPrompt); + }} + > + more feedback? + + + + )} + { + setShowCallout(!likeQuery); + setLikeQuery(!likeQuery); + if (dislikeQuery) { + setDislikeQuery(!dislikeQuery); + } + }} + /> + { + if (!dislikeQuery) { + useQueryCopilot.getState().openFeedbackModal(generatedQuery, false, userPrompt); + setLikeQuery(false); + } + setDislikeQuery(!dislikeQuery); + setShowCallout(false); + }} + /> + + + Copy code + + { + setShowDeletePopup(true); + }} + iconProps={{ iconName: "Delete" }} + style={{ margin: "0 10px", backgroundColor: "#FFF8F0", transition: "background-color 0.3s ease" }} + > + Delete code + + + )} + + + + setQuery(newQuery)} + onContentSelected={(selectedQuery: string) => setSelectedQuery(selectedQuery)} + /> + + queryDocumentsPerPage(firstItemIndex, queryIterator) + } + /> + + + + {isSamplePromptsOpen && } + {query !== "" && query.trim().length !== 0 && ( + - queryDocumentsPerPage(firstItemIndex, queryIterator)} - /> - - - - {isSamplePromptsOpen && } - {query !== "" && query.trim().length !== 0 && ( - - )} - + )} + +
); }; diff --git a/src/Explorer/QueryCopilot/__snapshots__/QueryCopilotTab.test.tsx.snap b/src/Explorer/QueryCopilot/__snapshots__/QueryCopilotTab.test.tsx.snap index 59d6034ba..c541fab8d 100644 --- a/src/Explorer/QueryCopilot/__snapshots__/QueryCopilotTab.test.tsx.snap +++ b/src/Explorer/QueryCopilot/__snapshots__/QueryCopilotTab.test.tsx.snap @@ -5,133 +5,148 @@ exports[`Query copilot tab snapshot test should render with initial input 1`] = className="tab-pane" style={ Object { - "height": "100%", "padding": 24, "width": "100%", } } > - - - - Copilot - - - - - - - - AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it. - - - Read preview terms - - - - + + Copilot + + + - - - - - - +
+ + + AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it. + + + Read preview terms + + + + + + + + + + + +
`;