[Query Copilot V2] Restructure code for V2 of copilot (#1577)

* Initial folder and code restructure

* Add snapshots

* Remove flag for local testing

* Remove unnecessary code

* Fix snapshot

* Update tests
This commit is contained in:
v-darkora 2023-08-16 10:10:21 +02:00 committed by GitHub
parent 96b88ac344
commit ceb66ed5b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 963 additions and 253 deletions

View File

@ -32,7 +32,7 @@ import { WelcomeModal } from "Explorer/QueryCopilot/Modal/WelcomeModal";
import { CopyPopup } from "Explorer/QueryCopilot/Popup/CopyPopup";
import { DeletePopup } from "Explorer/QueryCopilot/Popup/DeletePopup";
import { querySampleDocuments, submitFeedback } from "Explorer/QueryCopilot/QueryCopilotUtilities";
import { SamplePrompts, SamplePromptsProps } from "Explorer/QueryCopilot/SamplePrompts/SamplePrompts";
import { SamplePrompts, SamplePromptsProps } from "Explorer/QueryCopilot/Shared/SamplePrompts/SamplePrompts";
import { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection";
import { Action } from "Shared/Telemetry/TelemetryConstants";
import { traceFailure, traceStart, traceSuccess } from "Shared/Telemetry/TelemetryProcessor";

View File

@ -1,8 +1,8 @@
import { DefaultButton, FontIcon, IconButton, Image, Modal, Stack, Text } from "@fluentui/react";
import React, { Dispatch, SetStateAction } from "react";
import ComplexPrompts from "../../../../images/ComplexPrompts.svg";
import IntermediatePrompts from "../../../../images/IntermediatePrompts.svg";
import SimplePrompts from "../../../../images/SimplePrompts.svg";
import ComplexPrompts from "../../../../../images/ComplexPrompts.svg";
import IntermediatePrompts from "../../../../../images/IntermediatePrompts.svg";
import SimplePrompts from "../../../../../images/SimplePrompts.svg";
export interface SamplePromptsProps {
isSamplePromptsOpen: boolean;

View File

@ -1,243 +0,0 @@
import { IButtonStyles, IconButton, Image, Stack, Text, TextField } from "@fluentui/react";
import { SamplePrompts, SamplePromptsProps } from "Explorer/QueryCopilot/SamplePrompts/SamplePrompts";
import { WelcomeSidebarPopup } from "Explorer/QueryCopilot/Sidebar/WelcomeSidebarPopup";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react";
import CopilotIcon from "../../../../images/CopilotSidebarLogo.svg";
import HintIcon from "../../../../images/Hint.svg";
const sampleChatMessages: string[] = [
"Write a query to return last 10 records in the database",
'Write a query to return all records in this table created in the last thirty days which also have the record owner as "Contoso"',
];
const promptStyles: IButtonStyles = {
root: { border: "5px", selectors: { ":hover": { outline: "1px dashed #605e5c" } } },
label: { fontWeight: 400, textAlign: "left", paddingLeft: 8 },
};
export const QueryCopilotSidebar: React.FC = (): JSX.Element => {
const {
setWasCopilotUsed,
showCopilotSidebar,
setShowCopilotSidebar,
userPrompt,
setUserPrompt,
chatMessages,
setChatMessages,
showWelcomeSidebar,
isSamplePromptsOpen,
setIsSamplePromptsOpen,
} = useQueryCopilot();
const sampleProps: SamplePromptsProps = {
isSamplePromptsOpen: isSamplePromptsOpen,
setIsSamplePromptsOpen: setIsSamplePromptsOpen,
setTextBox: setUserPrompt,
};
const handleSendMessage = () => {
if (userPrompt.trim() !== "") {
setChatMessages([...chatMessages, userPrompt]);
setUserPrompt("");
}
};
const handleInputChange = (value: string) => {
setUserPrompt(value);
};
const handleEnterKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
handleSendMessage();
}
};
React.useEffect(() => {
if (showCopilotSidebar) {
setWasCopilotUsed(true);
}
}, []);
return (
<Stack style={{ width: "100%", height: "100%", backgroundColor: "#FAFAFA", overflow: "auto" }}>
<Stack style={{ margin: "15px 0px 0px 0px", padding: "5px" }}>
<Stack style={{ display: "flex", justifyContent: "space-between" }} horizontal verticalAlign="center">
<Stack horizontal verticalAlign="center">
<Image src={CopilotIcon} />
<Text style={{ marginLeft: "5px", fontWeight: "bold" }}>Copilot</Text>
<Text
style={{
background: "#f0f0f0",
fontSize: "10px",
padding: "2px 4px",
marginLeft: "5px",
borderRadius: "8px",
}}
>
Preview
</Text>
</Stack>
<IconButton
onClick={() => setShowCopilotSidebar(false)}
iconProps={{ iconName: "Cancel" }}
title="Exit"
ariaLabel="Exit"
style={{ color: "#424242", verticalAlign: "middle" }}
/>
</Stack>
</Stack>
{showWelcomeSidebar ? (
<Stack.Item styles={{ root: { textAlign: "center", verticalAlign: "middle" } }}>
<WelcomeSidebarPopup />
</Stack.Item>
) : (
<>
<Stack horizontalAlign="center" style={{ color: "#707070" }} tokens={{ padding: 8, childrenGap: 8 }}>
{new Date().toLocaleDateString("en-US", {
month: "long",
day: "numeric",
})}{" "}
{new Date().toLocaleTimeString("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true,
})}
</Stack>
<Stack style={{ flexGrow: 1, display: "flex", flexDirection: "column" }}>
<div style={{ flexGrow: 1, overflowY: "auto" }}>
<Stack
tokens={{ padding: 16, childrenGap: 12 }}
style={{
backgroundColor: "white",
margin: "5px 10px",
borderRadius: "8px",
}}
>
<Text variant="medium">
Hello, I am Cosmos Db&apos;s copilot assistant. I can help you do the following things:
</Text>
<Stack tokens={{ childrenGap: 8 }}>
<Stack horizontal style={{ marginLeft: "15px" }} tokens={{ childrenGap: 8 }}>
<Text style={{ fontSize: "16px", lineHeight: "16px", verticalAlign: "middle" }}></Text>
<Text style={{ verticalAlign: "middle" }}>Generate queries based upon prompt you suggest</Text>
</Stack>
<Stack horizontal style={{ marginLeft: "15px" }} tokens={{ childrenGap: 8 }}>
<Text style={{ fontSize: "16px", lineHeight: "16px", verticalAlign: "middle" }}></Text>
<Text style={{ verticalAlign: "middle" }}>
Explain and provide alternate queries for a query suggested by you
</Text>
</Stack>
<Stack horizontal style={{ marginLeft: "15px" }} tokens={{ childrenGap: 8 }}>
<Text style={{ fontSize: "16px", lineHeight: "16px", verticalAlign: "middle" }}></Text>
<Text style={{ verticalAlign: "middle" }}>Help answer questions about Cosmos DB</Text>
</Stack>
</Stack>
<Text variant="medium">
To get started, ask me a question or use one of the sample prompts to generate a query. AI-generated
content may be incorrect.
</Text>
</Stack>
{chatMessages.map((message, index) => (
<Stack
key={index}
horizontalAlign="center"
tokens={{ padding: 8, childrenGap: 8 }}
style={{
backgroundColor: "#E0E7FF",
borderRadius: "8px",
margin: "5px 10px",
textAlign: "start",
}}
>
{message}
</Stack>
))}
</div>
{chatMessages.length === 0 && (
<Stack
horizontalAlign="end"
verticalAlign="end"
style={{
display: "flex",
alignItems: "center",
padding: "10px",
margin: "10px",
}}
>
<Text
onClick={() => handleInputChange(sampleChatMessages[0])}
style={{
cursor: "pointer",
border: "1.5px solid #B0BEFF",
width: "100%",
padding: "2px",
borderRadius: "4px",
marginBottom: "5px",
}}
>
{sampleChatMessages[0]}
</Text>
<Text
onClick={() => handleInputChange(sampleChatMessages[1])}
style={{
cursor: "pointer",
border: "1.5px solid #B0BEFF",
width: "100%",
padding: "2px",
borderRadius: "4px",
marginBottom: "5px",
}}
>
{sampleChatMessages[1]}
</Text>
</Stack>
)}
<Stack
horizontal
horizontalAlign="end"
verticalAlign="end"
style={{
display: "flex",
alignItems: "center",
borderRadius: "20px",
background: "white",
padding: "5px",
margin: "5px",
}}
>
<Stack>
<Image src={HintIcon} styles={promptStyles} onClick={() => setIsSamplePromptsOpen(true)} />
<SamplePrompts sampleProps={sampleProps} />
</Stack>
<TextField
placeholder="Write your own prompt or ask a question"
value={userPrompt}
onChange={(_, newValue) => handleInputChange(newValue)}
onKeyDown={handleEnterKeyPress}
multiline
resizable={false}
styles={{
root: {
width: "100%",
height: "80px",
borderRadius: "20px",
padding: "8px",
border: "none",
outline: "none",
marginLeft: "10px",
},
fieldGroup: { border: "none" },
}}
/>
<IconButton iconProps={{ iconName: "Send" }} onClick={handleSendMessage} />
</Stack>
</Stack>
</>
)}
</Stack>
);
};

View File

@ -0,0 +1,10 @@
import { shallow } from "enzyme";
import React from "react";
import { SampleBubble } from "./SampleBubble";
describe("Sample Bubble snapshot test", () => {
it("should render ", () => {
const wrapper = shallow(<SampleBubble />);
expect(wrapper).toMatchSnapshot();
});
});

View File

@ -0,0 +1,42 @@
import { Stack, Text } from "@fluentui/react";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react";
export const SampleBubble: React.FC = (): JSX.Element => {
const { setUserPrompt } = useQueryCopilot();
const sampleChatMessages: string[] = [
"Write a query to return last 10 records in the database",
'Write a query to return all records in this table created in the last thirty days which also have the record owner as "Contoso"',
];
return (
<Stack
horizontalAlign="end"
verticalAlign="end"
style={{
display: "flex",
alignItems: "center",
padding: "10px",
margin: "10px",
}}
>
{sampleChatMessages.map((text, index) => (
<Text
key={index}
onClick={() => setUserPrompt(text)}
style={{
cursor: "pointer",
border: "1.5px solid #B0BEFF",
width: "100%",
padding: "2px",
borderRadius: "4px",
marginBottom: "5px",
}}
>
{text}
</Text>
))}
</Stack>
);
};

View File

@ -0,0 +1,49 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Sample Bubble snapshot test should render 1`] = `
<Stack
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"display": "flex",
"margin": "10px",
"padding": "10px",
}
}
verticalAlign="end"
>
<Text
key="0"
onClick={[Function]}
style={
Object {
"border": "1.5px solid #B0BEFF",
"borderRadius": "4px",
"cursor": "pointer",
"marginBottom": "5px",
"padding": "2px",
"width": "100%",
}
}
>
Write a query to return last 10 records in the database
</Text>
<Text
key="1"
onClick={[Function]}
style={
Object {
"border": "1.5px solid #B0BEFF",
"borderRadius": "4px",
"cursor": "pointer",
"marginBottom": "5px",
"padding": "2px",
"width": "100%",
}
}
>
Write a query to return all records in this table created in the last thirty days which also have the record owner as "Contoso"
</Text>
</Stack>
`;

View File

@ -0,0 +1,13 @@
import { shallow } from "enzyme";
import React from "react";
import { WelcomeBubble } from "./WelcomeBubble";
const mockedDate = new Date(2023, 7, 15);
jest.spyOn(global, "Date").mockImplementation(() => (mockedDate as unknown) as string);
describe("Welcome Bubble snapshot test", () => {
it("should render ", () => {
const wrapper = shallow(<WelcomeBubble />);
expect(wrapper).toMatchSnapshot();
});
});

View File

@ -0,0 +1,52 @@
import { Stack, Text } from "@fluentui/react";
import React from "react";
export const WelcomeBubble: React.FC = (): JSX.Element => {
return (
<Stack>
<Stack horizontalAlign="center" style={{ color: "#707070" }} tokens={{ padding: 8, childrenGap: 8 }}>
{new Date().toLocaleDateString("en-US", {
month: "long",
day: "numeric",
})}{" "}
{new Date().toLocaleTimeString("en-US", {
hour: "numeric",
minute: "numeric",
hour12: true,
})}
</Stack>
<Stack
tokens={{ padding: 16, childrenGap: 12 }}
style={{
backgroundColor: "white",
margin: "5px 10px",
borderRadius: "8px",
}}
>
<Text variant="medium">
Hello, I am Cosmos Db&apos;s copilot assistant. I can help you do the following things:
</Text>
<Stack tokens={{ childrenGap: 8 }}>
<Stack horizontal style={{ marginLeft: "15px" }} tokens={{ childrenGap: 8 }}>
<Text style={{ fontSize: "16px", lineHeight: "16px", verticalAlign: "middle" }}></Text>
<Text style={{ verticalAlign: "middle" }}>Generate queries based upon prompt you suggest</Text>
</Stack>
<Stack horizontal style={{ marginLeft: "15px" }} tokens={{ childrenGap: 8 }}>
<Text style={{ fontSize: "16px", lineHeight: "16px", verticalAlign: "middle" }}></Text>
<Text style={{ verticalAlign: "middle" }}>
Explain and provide alternate queries for a query suggested by you
</Text>
</Stack>
<Stack horizontal style={{ marginLeft: "15px" }} tokens={{ childrenGap: 8 }}>
<Text style={{ fontSize: "16px", lineHeight: "16px", verticalAlign: "middle" }}></Text>
<Text style={{ verticalAlign: "middle" }}>Help answer questions about Cosmos DB</Text>
</Stack>
</Stack>
<Text variant="medium">
To get started, ask me a question or use one of the sample prompts to generate a query. AI-generated content
may be incorrect.
</Text>
</Stack>
</Stack>
);
};

View File

@ -0,0 +1,160 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Welcome Bubble snapshot test should render 1`] = `
<Stack>
<Stack
horizontalAlign="center"
style={
Object {
"color": "#707070",
}
}
tokens={
Object {
"childrenGap": 8,
"padding": 8,
}
}
>
August 15
12:00 AM
</Stack>
<Stack
style={
Object {
"backgroundColor": "white",
"borderRadius": "8px",
"margin": "5px 10px",
}
}
tokens={
Object {
"childrenGap": 12,
"padding": 16,
}
}
>
<Text
variant="medium"
>
Hello, I am Cosmos Db's copilot assistant. I can help you do the following things:
</Text>
<Stack
tokens={
Object {
"childrenGap": 8,
}
}
>
<Stack
horizontal={true}
style={
Object {
"marginLeft": "15px",
}
}
tokens={
Object {
"childrenGap": 8,
}
}
>
<Text
style={
Object {
"fontSize": "16px",
"lineHeight": "16px",
"verticalAlign": "middle",
}
}
>
</Text>
<Text
style={
Object {
"verticalAlign": "middle",
}
}
>
Generate queries based upon prompt you suggest
</Text>
</Stack>
<Stack
horizontal={true}
style={
Object {
"marginLeft": "15px",
}
}
tokens={
Object {
"childrenGap": 8,
}
}
>
<Text
style={
Object {
"fontSize": "16px",
"lineHeight": "16px",
"verticalAlign": "middle",
}
}
>
</Text>
<Text
style={
Object {
"verticalAlign": "middle",
}
}
>
Explain and provide alternate queries for a query suggested by you
</Text>
</Stack>
<Stack
horizontal={true}
style={
Object {
"marginLeft": "15px",
}
}
tokens={
Object {
"childrenGap": 8,
}
}
>
<Text
style={
Object {
"fontSize": "16px",
"lineHeight": "16px",
"verticalAlign": "middle",
}
}
>
</Text>
<Text
style={
Object {
"verticalAlign": "middle",
}
}
>
Help answer questions about Cosmos DB
</Text>
</Stack>
</Stack>
<Text
variant="medium"
>
To get started, ask me a question or use one of the sample prompts to generate a query. AI-generated content may be incorrect.
</Text>
</Stack>
</Stack>
`;

View File

@ -0,0 +1,10 @@
import { shallow } from "enzyme";
import React from "react";
import { Footer } from "./Footer";
describe("Footer snapshot test", () => {
it("should render ", () => {
const wrapper = shallow(<Footer />);
expect(wrapper).toMatchSnapshot();
});
});

View File

@ -0,0 +1,83 @@
import { IButtonStyles, IconButton, Image, Stack, TextField } from "@fluentui/react";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react";
import HintIcon from "../../../../../images/Hint.svg";
import { SamplePrompts, SamplePromptsProps } from "../../Shared/SamplePrompts/SamplePrompts";
export const Footer: React.FC = (): JSX.Element => {
const {
userPrompt,
setUserPrompt,
chatMessages,
setChatMessages,
isSamplePromptsOpen,
setIsSamplePromptsOpen,
} = useQueryCopilot();
const promptStyles: IButtonStyles = {
root: { border: "5px", selectors: { ":hover": { outline: "1px dashed #605e5c" } } },
label: { fontWeight: 400, textAlign: "left", paddingLeft: 8 },
};
const sampleProps: SamplePromptsProps = {
isSamplePromptsOpen: isSamplePromptsOpen,
setIsSamplePromptsOpen: setIsSamplePromptsOpen,
setTextBox: setUserPrompt,
};
const handleEnterKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
handleSendMessage();
}
};
const handleSendMessage = () => {
if (userPrompt.trim() !== "") {
setChatMessages([...chatMessages, userPrompt]);
setUserPrompt("");
}
};
return (
<Stack
horizontal
horizontalAlign="end"
verticalAlign="end"
style={{
display: "flex",
alignItems: "center",
borderRadius: "20px",
background: "white",
padding: "5px",
margin: "5px",
}}
>
<Stack>
<Image src={HintIcon} styles={promptStyles} onClick={() => setIsSamplePromptsOpen(true)} />
<SamplePrompts sampleProps={sampleProps} />
</Stack>
<TextField
placeholder="Write your own prompt or ask a question"
value={userPrompt}
onChange={(_, newValue) => setUserPrompt(newValue)}
onKeyDown={handleEnterKeyPress}
multiline
resizable={false}
styles={{
root: {
width: "100%",
height: "80px",
borderRadius: "20px",
padding: "8px",
border: "none",
outline: "none",
marginLeft: "10px",
},
fieldGroup: { border: "none" },
}}
/>
<IconButton iconProps={{ iconName: "Send" }} onClick={handleSendMessage} />
</Stack>
);
};

View File

@ -0,0 +1,84 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Footer snapshot test should render 1`] = `
<Stack
horizontal={true}
horizontalAlign="end"
style={
Object {
"alignItems": "center",
"background": "white",
"borderRadius": "20px",
"display": "flex",
"margin": "5px",
"padding": "5px",
}
}
verticalAlign="end"
>
<Stack>
<Image
onClick={[Function]}
src=""
styles={
Object {
"label": Object {
"fontWeight": 400,
"paddingLeft": 8,
"textAlign": "left",
},
"root": Object {
"border": "5px",
"selectors": Object {
":hover": Object {
"outline": "1px dashed #605e5c",
},
},
},
}
}
/>
<SamplePrompts
sampleProps={
Object {
"isSamplePromptsOpen": false,
"setIsSamplePromptsOpen": [Function],
"setTextBox": [Function],
}
}
/>
</Stack>
<StyledTextFieldBase
multiline={true}
onChange={[Function]}
onKeyDown={[Function]}
placeholder="Write your own prompt or ask a question"
resizable={false}
styles={
Object {
"fieldGroup": Object {
"border": "none",
},
"root": Object {
"border": "none",
"borderRadius": "20px",
"height": "80px",
"marginLeft": "10px",
"outline": "none",
"padding": "8px",
"width": "100%",
},
}
}
value=""
/>
<CustomizedIconButton
iconProps={
Object {
"iconName": "Send",
}
}
onClick={[Function]}
/>
</Stack>
`;

View File

@ -0,0 +1,10 @@
import { shallow } from "enzyme";
import React from "react";
import { Header } from "./Header";
describe("Header snapshot test", () => {
it("should render ", () => {
const wrapper = shallow(<Header />);
expect(wrapper).toMatchSnapshot();
});
});

View File

@ -0,0 +1,39 @@
import { IconButton, Image, Stack, Text } from "@fluentui/react";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react";
import CopilotIcon from "../../../../../images/CopilotSidebarLogo.svg";
export const Header: React.FC = (): JSX.Element => {
const { setShowCopilotSidebar } = useQueryCopilot();
return (
<Stack
style={{ margin: "15px 0px 0px 0px", padding: "5px", display: "flex", justifyContent: "space-between" }}
horizontal
verticalAlign="center"
>
<Stack horizontal verticalAlign="center">
<Image src={CopilotIcon} />
<Text style={{ marginLeft: "5px", fontWeight: "bold" }}>Copilot</Text>
<Text
style={{
background: "#f0f0f0",
fontSize: "10px",
padding: "2px 4px",
marginLeft: "5px",
borderRadius: "8px",
}}
>
Preview
</Text>
</Stack>
<IconButton
onClick={() => setShowCopilotSidebar(false)}
iconProps={{ iconName: "Cancel" }}
title="Exit"
ariaLabel="Exit"
style={{ color: "#424242", verticalAlign: "middle" }}
/>
</Stack>
);
};

View File

@ -0,0 +1,64 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Header snapshot test should render 1`] = `
<Stack
horizontal={true}
style={
Object {
"display": "flex",
"justifyContent": "space-between",
"margin": "15px 0px 0px 0px",
"padding": "5px",
}
}
verticalAlign="center"
>
<Stack
horizontal={true}
verticalAlign="center"
>
<Image
src=""
/>
<Text
style={
Object {
"fontWeight": "bold",
"marginLeft": "5px",
}
}
>
Copilot
</Text>
<Text
style={
Object {
"background": "#f0f0f0",
"borderRadius": "8px",
"fontSize": "10px",
"marginLeft": "5px",
"padding": "2px 4px",
}
}
>
Preview
</Text>
</Stack>
<CustomizedIconButton
ariaLabel="Exit"
iconProps={
Object {
"iconName": "Cancel",
}
}
onClick={[Function]}
style={
Object {
"color": "#424242",
"verticalAlign": "middle",
}
}
title="Exit"
/>
</Stack>
`;

View File

@ -0,0 +1,10 @@
import { shallow } from "enzyme";
import React from "react";
import { WelcomeSidebarModal } from "./WelcomeSidebarModal";
describe("Footer snapshot test", () => {
it("should render ", () => {
const wrapper = shallow(<WelcomeSidebarModal />);
expect(wrapper).toMatchSnapshot();
});
});

View File

@ -1,12 +1,12 @@
import { Image, Link, PrimaryButton, Stack, Text } from "@fluentui/react";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react";
import Database from "../../../../images/CopilotDatabase.svg";
import Flash from "../../../../images/CopilotFlash.svg";
import CopilotSidebarWelcomeIllustration from "../../../../images/CopilotSidebarWelcomeIllustration.svg";
import Thumb from "../../../../images/CopilotThumb.svg";
import Database from "../../../../../images/CopilotDatabase.svg";
import Flash from "../../../../../images/CopilotFlash.svg";
import CopilotSidebarWelcomeIllustration from "../../../../../images/CopilotSidebarWelcomeIllustration.svg";
import Thumb from "../../../../../images/CopilotThumb.svg";
export const WelcomeSidebarPopup: React.FC = (): JSX.Element => {
export const WelcomeSidebarModal: React.FC = (): JSX.Element => {
const { setShowWelcomeSidebar } = useQueryCopilot();
const hideModal = () => {

View File

@ -0,0 +1,243 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Footer snapshot test should render 1`] = `
<Stack
style={
Object {
"backgroundColor": "#FAFAFA",
"height": "100%",
"overflow": "auto",
"width": "100%",
}
}
>
<div
style={
Object {
"backgroundColor": "white",
"borderRadius": "20px",
"boxSizing": "border-box",
"margin": "20px 10px",
"maxHeight": "100%",
"padding": "20px",
}
}
>
<Stack
horizontalAlign="center"
verticalAlign="center"
>
<Image
src=""
/>
</Stack>
<Stack>
<StackItem
align="center"
style={
Object {
"marginBottom": "10px",
}
}
>
<Text
className="title bold"
>
Welcome to Copilot in CosmosDB
</Text>
</StackItem>
<StackItem
style={
Object {
"marginBottom": "15px",
}
}
>
<Stack>
<Stack
horizontal={true}
>
<StackItem
align="start"
>
<Image
src=""
/>
</StackItem>
<StackItem
align="center"
style={
Object {
"marginLeft": "10px",
}
}
>
<Text
style={
Object {
"fontWeight": 600,
}
}
>
Let copilot do the work for you
<br />
</Text>
</StackItem>
</Stack>
<StackItem
style={
Object {
"marginLeft": "25px",
"textAlign": "start",
}
}
>
<Text>
Ask Copilot to generate a query by describing the query in your words.
<br />
<StyledLinkBase
href="http://aka.ms/cdb-copilot-learn-more"
>
Learn more
</StyledLinkBase>
</Text>
</StackItem>
</Stack>
</StackItem>
<StackItem
style={
Object {
"marginBottom": "15px",
}
}
>
<Stack>
<Stack
horizontal={true}
>
<StackItem
align="start"
>
<Image
src=""
/>
</StackItem>
<StackItem
align="center"
style={
Object {
"marginLeft": "10px",
}
}
>
<Text
style={
Object {
"fontWeight": 600,
}
}
>
Use your judgement
<br />
</Text>
</StackItem>
</Stack>
<StackItem
style={
Object {
"marginLeft": "25px",
"textAlign": "start",
}
}
>
<Text>
AI-generated content can have mistakes. Make sure its accurate and appropriate before using it.
<br />
<StyledLinkBase
href="http://aka.ms/cdb-copilot-preview-terms"
>
Read preview terms
</StyledLinkBase>
</Text>
</StackItem>
</Stack>
</StackItem>
<StackItem
style={
Object {
"marginBottom": "15px",
}
}
>
<Stack>
<Stack
horizontal={true}
>
<StackItem
align="start"
>
<Image
src=""
/>
</StackItem>
<StackItem
align="center"
style={
Object {
"marginLeft": "10px",
}
}
>
<Text
style={
Object {
"fontWeight": 600,
}
}
>
Copilot currently works only a sample database
<br />
</Text>
</StackItem>
</Stack>
<StackItem
style={
Object {
"marginLeft": "25px",
"textAlign": "start",
}
}
>
<Text>
Copilot is setup on a sample database we have configured for you at no cost
<br />
<StyledLinkBase
href="http://aka.ms/cdb-copilot-learn-more"
>
Learn more
</StyledLinkBase>
</Text>
</StackItem>
</Stack>
</StackItem>
</Stack>
<Stack>
<StackItem
align="center"
>
<CustomizedPrimaryButton
onClick={[Function]}
style={
Object {
"height": "32px",
"width": "224px",
}
}
>
Get Started
</CustomizedPrimaryButton>
</StackItem>
</Stack>
</div>
</Stack>
`;

View File

@ -0,0 +1,10 @@
import { shallow } from "enzyme";
import React from "react";
import { QueryCopilotSidebar } from "./QueryCopilotSidebar";
describe("Footer snapshot test", () => {
it("should render ", () => {
const wrapper = shallow(<QueryCopilotSidebar />);
expect(wrapper).toMatchSnapshot();
});
});

View File

@ -0,0 +1,57 @@
import { Stack } from "@fluentui/react";
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";
import { Header } from "Explorer/QueryCopilot/V2/Header/Header";
import { useQueryCopilot } from "hooks/useQueryCopilot";
import React from "react";
import { WelcomeSidebarModal } from "../Modal/WelcomeSidebarModal";
export const QueryCopilotSidebar: React.FC = (): JSX.Element => {
const { setWasCopilotUsed, showCopilotSidebar, chatMessages, showWelcomeSidebar } = useQueryCopilot();
React.useEffect(() => {
if (showCopilotSidebar) {
setWasCopilotUsed(true);
}
}, []);
return (
<Stack style={{ width: "100%", height: "100%", backgroundColor: "#FAFAFA", overflow: "auto" }}>
<Header />
{showWelcomeSidebar ? (
<WelcomeSidebarModal />
) : (
<>
<Stack
style={{
flexGrow: 1,
display: "flex",
flexDirection: "column",
overflowY: "auto",
}}
>
<WelcomeBubble />
{chatMessages.map((message, index) => (
<Stack
key={index}
horizontalAlign="center"
tokens={{ padding: 8, childrenGap: 8 }}
style={{
backgroundColor: "#E0E7FF",
borderRadius: "8px",
margin: "5px 10px",
textAlign: "start",
}}
>
{message}
</Stack>
))}
{chatMessages.length === 0 && <SampleBubble />}
</Stack>
<Footer />
</>
)}
</Stack>
);
};

View File

@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Footer snapshot test should render 1`] = `
<Stack
style={
Object {
"backgroundColor": "#FAFAFA",
"height": "100%",
"overflow": "auto",
"width": "100%",
}
}
>
<Header />
<WelcomeSidebarModal />
</Stack>
`;

View File

@ -1,5 +1,5 @@
import { FeedOptions } from "@azure/cosmos";
import { QueryCopilotSidebar } from "Explorer/QueryCopilot/Sidebar/QueryCopilotSidebar";
import { QueryCopilotSidebar } from "Explorer/QueryCopilot/V2/Sidebar/QueryCopilotSidebar";
import { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection";
import { useDatabases } from "Explorer/useDatabases";
import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";