mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-04-21 09:09:23 +01:00
[Query Copilot] Scrollable Copilot tab, improved history and minor fixes (#1536)
Co-authored-by: Predrag Klepic <v-prklepic@microsoft.com>
This commit is contained in:
parent
de3e56bb99
commit
7375cc717c
@ -44,7 +44,6 @@ import ExecuteQueryIcon from "../../../images/ExecuteQuery.svg";
|
|||||||
import HintIcon from "../../../images/Hint.svg";
|
import HintIcon from "../../../images/Hint.svg";
|
||||||
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
|
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
|
||||||
import RecentIcon from "../../../images/Recent.svg";
|
import RecentIcon from "../../../images/Recent.svg";
|
||||||
import SamplePromptsIcon from "../../../images/SamplePromptsIcon.svg";
|
|
||||||
import XErrorMessage from "../../../images/X-errorMessage.svg";
|
import XErrorMessage from "../../../images/X-errorMessage.svg";
|
||||||
import SaveQueryIcon from "../../../images/save-cosmos.svg";
|
import SaveQueryIcon from "../../../images/save-cosmos.svg";
|
||||||
import { useTabs } from "../../hooks/useTabs";
|
import { useTabs } from "../../hooks/useTabs";
|
||||||
@ -122,12 +121,12 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const cachedHistoriesString = localStorage.getItem(`${userContext.databaseAccount?.id}-queryCopilotHistories`);
|
const cachedHistoriesString = localStorage.getItem(`${userContext.databaseAccount?.id}-queryCopilotHistories`);
|
||||||
const cachedHistories = cachedHistoriesString?.split(",");
|
const cachedHistories = cachedHistoriesString?.split("|");
|
||||||
const [histories, setHistories] = useState<string[]>(cachedHistories || []);
|
const [histories, setHistories] = useState<string[]>(cachedHistories || []);
|
||||||
const suggestedPrompts: SuggestedPrompt[] = [
|
const suggestedPrompts: SuggestedPrompt[] = [
|
||||||
{ id: 1, text: "Give me all customers whose names start with C" },
|
{ id: 1, text: 'Show all products that have the word "ultra" in the name or description' },
|
||||||
{ id: 2, text: "Show me all customers" },
|
{ id: 2, text: "What are all of the possible categories for the products, and their counts?" },
|
||||||
{ id: 3, text: "Show me all customers who bought a bike in 2019" },
|
{ id: 3, text: 'Show me all products that have been reviewed by someone with a username that contains "bob"' },
|
||||||
];
|
];
|
||||||
const [filteredHistories, setFilteredHistories] = useState<string[]>(histories);
|
const [filteredHistories, setFilteredHistories] = useState<string[]>(histories);
|
||||||
const [filteredSuggestedPrompts, setFilteredSuggestedPrompts] = useState<SuggestedPrompt[]>(suggestedPrompts);
|
const [filteredSuggestedPrompts, setFilteredSuggestedPrompts] = useState<SuggestedPrompt[]>(suggestedPrompts);
|
||||||
@ -149,9 +148,16 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateHistories = (): void => {
|
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);
|
setHistories(newHistories);
|
||||||
localStorage.setItem(`${userContext.databaseAccount.id}-queryCopilotHistories`, newHistories.join(","));
|
localStorage.setItem(`${userContext.databaseAccount.id}-queryCopilotHistories`, newHistories.join("|"));
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateSQLQuery = async (): Promise<void> => {
|
const generateSQLQuery = async (): Promise<void> => {
|
||||||
@ -260,16 +266,17 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
disabled: query?.trim() === "",
|
disabled: query?.trim() === "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const samplePromptsBtn = {
|
// Sample Prompts temporary disabled due current design
|
||||||
iconSrc: SamplePromptsIcon,
|
// const samplePromptsBtn = {
|
||||||
iconAlt: "Sample Prompts",
|
// iconSrc: SamplePromptsIcon,
|
||||||
onCommandClick: () => setIsSamplePromptsOpen(true),
|
// iconAlt: "Sample Prompts",
|
||||||
commandButtonLabel: "Sample Prompts",
|
// onCommandClick: () => setIsSamplePromptsOpen(true),
|
||||||
ariaLabel: "Sample Prompts",
|
// commandButtonLabel: "Sample Prompts",
|
||||||
hasPopup: false,
|
// ariaLabel: "Sample Prompts",
|
||||||
};
|
// hasPopup: false,
|
||||||
|
// };
|
||||||
|
|
||||||
return [executeQueryBtn, saveQueryBtn, samplePromptsBtn];
|
return [executeQueryBtn, saveQueryBtn];
|
||||||
};
|
};
|
||||||
const showTeachingBubble = (): void => {
|
const showTeachingBubble = (): void => {
|
||||||
if (!inputEdited.current) {
|
if (!inputEdited.current) {
|
||||||
@ -301,7 +308,8 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack className="tab-pane" style={{ padding: 24, width: "100%", height: "100%" }}>
|
<Stack className="tab-pane" style={{ padding: 24, width: "100%" }}>
|
||||||
|
<div style={{ overflowY: "auto", height: "100%" }}>
|
||||||
<Stack horizontal verticalAlign="center">
|
<Stack horizontal verticalAlign="center">
|
||||||
<Image src={CopilotIcon} />
|
<Image src={CopilotIcon} />
|
||||||
<Text style={{ marginLeft: 8, fontWeight: 600, fontSize: 16 }}>Copilot</Text>
|
<Text style={{ marginLeft: 8, fontWeight: 600, fontSize: 16 }}>Copilot</Text>
|
||||||
@ -454,7 +462,8 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
)}
|
)}
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
<Text style={{ marginTop: 8, marginBottom: 24, fontSize: 12 }}>
|
<Stack style={{ marginTop: 8, marginBottom: 24 }}>
|
||||||
|
<Text style={{ fontSize: 12 }}>
|
||||||
AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.{" "}
|
AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.{" "}
|
||||||
<Link href="" target="_blank">
|
<Link href="" target="_blank">
|
||||||
Read preview terms
|
Read preview terms
|
||||||
@ -468,6 +477,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
</Text>
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
{showFeedbackBar && (
|
{showFeedbackBar && (
|
||||||
<Stack style={{ backgroundColor: "#FFF8F0", padding: "2px 8px" }} horizontal verticalAlign="center">
|
<Stack style={{ backgroundColor: "#FFF8F0", padding: "2px 8px" }} horizontal verticalAlign="center">
|
||||||
@ -556,7 +566,9 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
error={errorMessage}
|
error={errorMessage}
|
||||||
queryResults={queryResults}
|
queryResults={queryResults}
|
||||||
isExecuting={isExecuting}
|
isExecuting={isExecuting}
|
||||||
executeQueryDocumentsPage={(firstItemIndex: number) => queryDocumentsPerPage(firstItemIndex, queryIterator)}
|
executeQueryDocumentsPage={(firstItemIndex: number) =>
|
||||||
|
queryDocumentsPerPage(firstItemIndex, queryIterator)
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</SplitterLayout>
|
</SplitterLayout>
|
||||||
</Stack>
|
</Stack>
|
||||||
@ -572,6 +584,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<CopyPopup showCopyPopup={showCopyPopup} setShowCopyPopup={setshowCopyPopup} />
|
<CopyPopup showCopyPopup={showCopyPopup} setShowCopyPopup={setshowCopyPopup} />
|
||||||
|
</div>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -5,12 +5,19 @@ exports[`Query copilot tab snapshot test should render with initial input 1`] =
|
|||||||
className="tab-pane"
|
className="tab-pane"
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"height": "100%",
|
|
||||||
"padding": 24,
|
"padding": 24,
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"height": "100%",
|
||||||
|
"overflowY": "auto",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
<Stack
|
<Stack
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
verticalAlign="center"
|
verticalAlign="center"
|
||||||
@ -76,12 +83,18 @@ exports[`Query copilot tab snapshot test should render with initial input 1`] =
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
<Stack
|
||||||
|
style={
|
||||||
|
Object {
|
||||||
|
"marginBottom": 24,
|
||||||
|
"marginTop": 8,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
<Text
|
<Text
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"fontSize": 12,
|
"fontSize": 12,
|
||||||
"marginBottom": 24,
|
|
||||||
"marginTop": 8,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -94,6 +107,7 @@ exports[`Query copilot tab snapshot test should render with initial input 1`] =
|
|||||||
Read preview terms
|
Read preview terms
|
||||||
</StyledLinkBase>
|
</StyledLinkBase>
|
||||||
</Text>
|
</Text>
|
||||||
|
</Stack>
|
||||||
<Stack
|
<Stack
|
||||||
className="tabPaneContentContainer"
|
className="tabPaneContentContainer"
|
||||||
>
|
>
|
||||||
@ -133,5 +147,6 @@ exports[`Query copilot tab snapshot test should render with initial input 1`] =
|
|||||||
setShowCopyPopup={[Function]}
|
setShowCopyPopup={[Function]}
|
||||||
showCopyPopup={false}
|
showCopyPopup={false}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
</Stack>
|
</Stack>
|
||||||
`;
|
`;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user