mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 09:20:16 +00:00
[Query Copilot] Copilot V2 Retrieving bubble (#1579)
* Changing order of the features * test name changed * updates snapshots * Bubble implementation * Bubble tests implemented * Correction for CopilotSampleDB implementation * rollback to previous query tab changes --------- Co-authored-by: Predrag Klepic <v-prklepic@microsoft.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
@keyframes loadingAnimation {
|
||||
0% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { DefaultButton } from "@fluentui/react";
|
||||
import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
import { RetrievingBubble } from "./RetrievingBubble";
|
||||
|
||||
const mockUseQueryCopilot = {
|
||||
isGeneratingQuery: false,
|
||||
setIsGeneratingQuery: jest.fn(),
|
||||
isGeneratingExplanation: false,
|
||||
setIsGeneratingExplanation: jest.fn(),
|
||||
shouldIncludeInMessages: true,
|
||||
setShouldIncludeInMessages: jest.fn(),
|
||||
};
|
||||
|
||||
jest.mock("hooks/useQueryCopilot", () => ({
|
||||
useQueryCopilot: jest.fn(() => mockUseQueryCopilot),
|
||||
}));
|
||||
|
||||
describe("RetrievingBubble", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockUseQueryCopilot.isGeneratingQuery = false;
|
||||
mockUseQueryCopilot.isGeneratingExplanation = false;
|
||||
mockUseQueryCopilot.setIsGeneratingQuery.mockClear();
|
||||
mockUseQueryCopilot.setIsGeneratingExplanation.mockClear();
|
||||
mockUseQueryCopilot.setShouldIncludeInMessages.mockClear();
|
||||
});
|
||||
|
||||
it("should render properly when isGeneratingQuery is true", () => {
|
||||
mockUseQueryCopilot.isGeneratingQuery = true;
|
||||
const wrapper = shallow(<RetrievingBubble />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should render properly when isGeneratingExplanation is true", () => {
|
||||
mockUseQueryCopilot.isGeneratingExplanation = true;
|
||||
const wrapper = shallow(<RetrievingBubble />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("when isGeneratingQuery is true clicking stop generating button invokes the correct callbacks", () => {
|
||||
mockUseQueryCopilot.isGeneratingQuery = true;
|
||||
|
||||
const wrapper = shallow(<RetrievingBubble />);
|
||||
wrapper.find(DefaultButton).at(0).simulate("click");
|
||||
|
||||
expect(mockUseQueryCopilot.setIsGeneratingQuery).toHaveBeenCalledWith(false);
|
||||
expect(mockUseQueryCopilot.setIsGeneratingExplanation).toHaveBeenCalledTimes(0);
|
||||
expect(mockUseQueryCopilot.setShouldIncludeInMessages).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it("when isGeneratingExplanation is true clicking stop generating button invokes the correct callbacks", () => {
|
||||
mockUseQueryCopilot.isGeneratingExplanation = true;
|
||||
|
||||
const wrapper = shallow(<RetrievingBubble />);
|
||||
wrapper.find(DefaultButton).at(0).simulate("click");
|
||||
|
||||
expect(mockUseQueryCopilot.setIsGeneratingQuery).toHaveBeenCalledTimes(0);
|
||||
expect(mockUseQueryCopilot.setIsGeneratingExplanation).toHaveBeenCalledWith(false);
|
||||
expect(mockUseQueryCopilot.setShouldIncludeInMessages).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,98 @@
|
||||
import { DefaultButton, Image, Stack, Text } from "@fluentui/react";
|
||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||
import React from "react";
|
||||
import StopGeneratingIcon from "../../../../../../images/StopGenerating.svg";
|
||||
import "./RetrievingBubble.css";
|
||||
|
||||
export const RetrievingBubble = (): JSX.Element => {
|
||||
const {
|
||||
isGeneratingQuery,
|
||||
setIsGeneratingQuery,
|
||||
isGeneratingExplanation,
|
||||
setIsGeneratingExplanation,
|
||||
shouldIncludeInMessages,
|
||||
setShouldIncludeInMessages,
|
||||
} = useQueryCopilot();
|
||||
|
||||
const stopGenerating = () => {
|
||||
if (isGeneratingQuery) {
|
||||
setIsGeneratingQuery(false);
|
||||
}
|
||||
if (isGeneratingExplanation) {
|
||||
setIsGeneratingExplanation(false);
|
||||
}
|
||||
if (shouldIncludeInMessages) {
|
||||
setShouldIncludeInMessages(false);
|
||||
}
|
||||
};
|
||||
|
||||
const bubbleContent = (bubbleType: string) => {
|
||||
return (
|
||||
<Stack
|
||||
horizontalAlign="end"
|
||||
verticalAlign="end"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
padding: "10px",
|
||||
margin: "10px",
|
||||
backgroundColor: "#FAFAFA",
|
||||
borderRadius: "8px",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "46px",
|
||||
backgroundColor: "white",
|
||||
padding: "12px 16px 16px 16px",
|
||||
gap: "12px",
|
||||
borderRadius: "8px",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Retriveing {bubbleType}
|
||||
</Text>
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "4px",
|
||||
backgroundColor: "#E6E6E6",
|
||||
borderRadius: "4px",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
width: "50%",
|
||||
height: "100%",
|
||||
backgroundColor: "#0078D4",
|
||||
animation: "loadingAnimation 2s linear infinite",
|
||||
}}
|
||||
></div>
|
||||
</div>
|
||||
<Stack
|
||||
horizontalAlign="center"
|
||||
verticalAlign="center"
|
||||
style={{ marginTop: "8px", gap: "8px", alignItems: "center" }}
|
||||
>
|
||||
<DefaultButton
|
||||
onClick={stopGenerating}
|
||||
styles={{ root: { border: "none", background: "none", padding: 0, color: "#424242" } }}
|
||||
style={{ color: "#424242" }}
|
||||
onRenderIcon={() => <Image src={StopGeneratingIcon} />}
|
||||
>
|
||||
Stop generating
|
||||
</DefaultButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{isGeneratingQuery && bubbleContent("queries")}
|
||||
{isGeneratingExplanation && bubbleContent("explanation")}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,183 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`RetrievingBubble should render properly when isGeneratingExplanation is true 1`] = `
|
||||
<Fragment>
|
||||
<Stack
|
||||
horizontalAlign="end"
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"backgroundColor": "#FAFAFA",
|
||||
"borderRadius": "8px",
|
||||
"display": "flex",
|
||||
"margin": "10px",
|
||||
"padding": "10px",
|
||||
}
|
||||
}
|
||||
verticalAlign="end"
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "white",
|
||||
"borderRadius": "8px",
|
||||
"fontWeight": "bold",
|
||||
"gap": "12px",
|
||||
"height": "46px",
|
||||
"padding": "12px 16px 16px 16px",
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
>
|
||||
Retriveing
|
||||
explanation
|
||||
</Text>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "#E6E6E6",
|
||||
"borderRadius": "4px",
|
||||
"height": "4px",
|
||||
"overflow": "hidden",
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"animation": "loadingAnimation 2s linear infinite",
|
||||
"backgroundColor": "#0078D4",
|
||||
"height": "100%",
|
||||
"width": "50%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Stack
|
||||
horizontalAlign="center"
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"gap": "8px",
|
||||
"marginTop": "8px",
|
||||
}
|
||||
}
|
||||
verticalAlign="center"
|
||||
>
|
||||
<CustomizedDefaultButton
|
||||
onClick={[Function]}
|
||||
onRenderIcon={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"color": "#424242",
|
||||
}
|
||||
}
|
||||
styles={
|
||||
Object {
|
||||
"root": Object {
|
||||
"background": "none",
|
||||
"border": "none",
|
||||
"color": "#424242",
|
||||
"padding": 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
Stop generating
|
||||
</CustomizedDefaultButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Fragment>
|
||||
`;
|
||||
|
||||
exports[`RetrievingBubble should render properly when isGeneratingQuery is true 1`] = `
|
||||
<Fragment>
|
||||
<Stack
|
||||
horizontalAlign="end"
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"backgroundColor": "#FAFAFA",
|
||||
"borderRadius": "8px",
|
||||
"display": "flex",
|
||||
"margin": "10px",
|
||||
"padding": "10px",
|
||||
}
|
||||
}
|
||||
verticalAlign="end"
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "white",
|
||||
"borderRadius": "8px",
|
||||
"fontWeight": "bold",
|
||||
"gap": "12px",
|
||||
"height": "46px",
|
||||
"padding": "12px 16px 16px 16px",
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
>
|
||||
Retriveing
|
||||
queries
|
||||
</Text>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"backgroundColor": "#E6E6E6",
|
||||
"borderRadius": "4px",
|
||||
"height": "4px",
|
||||
"overflow": "hidden",
|
||||
"width": "100%",
|
||||
}
|
||||
}
|
||||
>
|
||||
<div
|
||||
style={
|
||||
Object {
|
||||
"animation": "loadingAnimation 2s linear infinite",
|
||||
"backgroundColor": "#0078D4",
|
||||
"height": "100%",
|
||||
"width": "50%",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Stack
|
||||
horizontalAlign="center"
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"gap": "8px",
|
||||
"marginTop": "8px",
|
||||
}
|
||||
}
|
||||
verticalAlign="center"
|
||||
>
|
||||
<CustomizedDefaultButton
|
||||
onClick={[Function]}
|
||||
onRenderIcon={[Function]}
|
||||
style={
|
||||
Object {
|
||||
"color": "#424242",
|
||||
}
|
||||
}
|
||||
styles={
|
||||
Object {
|
||||
"root": Object {
|
||||
"background": "none",
|
||||
"border": "none",
|
||||
"color": "#424242",
|
||||
"padding": 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
>
|
||||
Stop generating
|
||||
</CustomizedDefaultButton>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Fragment>
|
||||
`;
|
||||
@@ -12,6 +12,7 @@ export const Footer: React.FC = (): JSX.Element => {
|
||||
setChatMessages,
|
||||
isSamplePromptsOpen,
|
||||
setIsSamplePromptsOpen,
|
||||
setIsGeneratingQuery,
|
||||
} = useQueryCopilot();
|
||||
|
||||
const promptStyles: IButtonStyles = {
|
||||
@@ -36,6 +37,7 @@ export const Footer: React.FC = (): JSX.Element => {
|
||||
if (userPrompt.trim() !== "") {
|
||||
setChatMessages([...chatMessages, userPrompt]);
|
||||
setUserPrompt("");
|
||||
setIsGeneratingQuery(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
import { WelcomeSidebarModal } from "./WelcomeSidebarModal";
|
||||
|
||||
describe("Footer snapshot test", () => {
|
||||
describe("WelcomeSidebarModal snapshot test", () => {
|
||||
it("should render ", () => {
|
||||
const wrapper = shallow(<WelcomeSidebarModal />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Footer snapshot test should render 1`] = `
|
||||
exports[`WelcomeSidebarModal snapshot test should render 1`] = `
|
||||
<Stack
|
||||
style={
|
||||
Object {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { shallow } from "enzyme";
|
||||
import React from "react";
|
||||
import { QueryCopilotSidebar } from "./QueryCopilotSidebar";
|
||||
|
||||
describe("Footer snapshot test", () => {
|
||||
describe("QueryCopilotSidebar snapshot test", () => {
|
||||
it("should render ", () => {
|
||||
const wrapper = shallow(<QueryCopilotSidebar />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Stack } from "@fluentui/react";
|
||||
import { RetrievingBubble } from "Explorer/QueryCopilot/V2/Bubbles/Retriveing/RetrievingBubble";
|
||||
import { SampleBubble } from "Explorer/QueryCopilot/V2/Bubbles/Sample/SampleBubble";
|
||||
import { WelcomeBubble } from "Explorer/QueryCopilot/V2/Bubbles/Welcome/WelcomeBubble";
|
||||
import { Footer } from "Explorer/QueryCopilot/V2/Footer/Footer";
|
||||
@@ -47,6 +48,9 @@ export const QueryCopilotSidebar: React.FC = (): JSX.Element => {
|
||||
{message}
|
||||
</Stack>
|
||||
))}
|
||||
|
||||
<RetrievingBubble />
|
||||
|
||||
{chatMessages.length === 0 && <SampleBubble />}
|
||||
</Stack>
|
||||
<Footer />
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Footer snapshot test should render 1`] = `
|
||||
exports[`QueryCopilotSidebar snapshot test should render 1`] = `
|
||||
<Stack
|
||||
style={
|
||||
Object {
|
||||
|
||||
Reference in New Issue
Block a user