mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-02-16 17:25:58 +00:00
[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:
parent
96b88ac344
commit
ceb66ed5b8
@ -32,7 +32,7 @@ import { WelcomeModal } from "Explorer/QueryCopilot/Modal/WelcomeModal";
|
|||||||
import { CopyPopup } from "Explorer/QueryCopilot/Popup/CopyPopup";
|
import { CopyPopup } from "Explorer/QueryCopilot/Popup/CopyPopup";
|
||||||
import { DeletePopup } from "Explorer/QueryCopilot/Popup/DeletePopup";
|
import { DeletePopup } from "Explorer/QueryCopilot/Popup/DeletePopup";
|
||||||
import { querySampleDocuments, submitFeedback } from "Explorer/QueryCopilot/QueryCopilotUtilities";
|
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 { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection";
|
||||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
import { traceFailure, traceStart, traceSuccess } from "Shared/Telemetry/TelemetryProcessor";
|
import { traceFailure, traceStart, traceSuccess } from "Shared/Telemetry/TelemetryProcessor";
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { DefaultButton, FontIcon, IconButton, Image, Modal, Stack, Text } from "@fluentui/react";
|
import { DefaultButton, FontIcon, IconButton, Image, Modal, Stack, Text } from "@fluentui/react";
|
||||||
import React, { Dispatch, SetStateAction } from "react";
|
import React, { Dispatch, SetStateAction } from "react";
|
||||||
import ComplexPrompts from "../../../../images/ComplexPrompts.svg";
|
import ComplexPrompts from "../../../../../images/ComplexPrompts.svg";
|
||||||
import IntermediatePrompts from "../../../../images/IntermediatePrompts.svg";
|
import IntermediatePrompts from "../../../../../images/IntermediatePrompts.svg";
|
||||||
import SimplePrompts from "../../../../images/SimplePrompts.svg";
|
import SimplePrompts from "../../../../../images/SimplePrompts.svg";
|
||||||
|
|
||||||
export interface SamplePromptsProps {
|
export interface SamplePromptsProps {
|
||||||
isSamplePromptsOpen: boolean;
|
isSamplePromptsOpen: boolean;
|
@ -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'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>
|
|
||||||
);
|
|
||||||
};
|
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
42
src/Explorer/QueryCopilot/V2/Bubbles/Sample/SampleBubble.tsx
Normal file
42
src/Explorer/QueryCopilot/V2/Bubbles/Sample/SampleBubble.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
@ -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>
|
||||||
|
`;
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -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'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>
|
||||||
|
);
|
||||||
|
};
|
@ -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>
|
||||||
|
`;
|
10
src/Explorer/QueryCopilot/V2/Footer/Footer.test.tsx
Normal file
10
src/Explorer/QueryCopilot/V2/Footer/Footer.test.tsx
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
83
src/Explorer/QueryCopilot/V2/Footer/Footer.tsx
Normal file
83
src/Explorer/QueryCopilot/V2/Footer/Footer.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
@ -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>
|
||||||
|
`;
|
10
src/Explorer/QueryCopilot/V2/Header/Header.test.tsx
Normal file
10
src/Explorer/QueryCopilot/V2/Header/Header.test.tsx
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
39
src/Explorer/QueryCopilot/V2/Header/Header.tsx
Normal file
39
src/Explorer/QueryCopilot/V2/Header/Header.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
@ -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>
|
||||||
|
`;
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -1,12 +1,12 @@
|
|||||||
import { Image, Link, PrimaryButton, Stack, Text } from "@fluentui/react";
|
import { Image, Link, PrimaryButton, Stack, Text } from "@fluentui/react";
|
||||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Database from "../../../../images/CopilotDatabase.svg";
|
import Database from "../../../../../images/CopilotDatabase.svg";
|
||||||
import Flash from "../../../../images/CopilotFlash.svg";
|
import Flash from "../../../../../images/CopilotFlash.svg";
|
||||||
import CopilotSidebarWelcomeIllustration from "../../../../images/CopilotSidebarWelcomeIllustration.svg";
|
import CopilotSidebarWelcomeIllustration from "../../../../../images/CopilotSidebarWelcomeIllustration.svg";
|
||||||
import Thumb from "../../../../images/CopilotThumb.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 { setShowWelcomeSidebar } = useQueryCopilot();
|
||||||
|
|
||||||
const hideModal = () => {
|
const hideModal = () => {
|
@ -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 it’s 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>
|
||||||
|
`;
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
57
src/Explorer/QueryCopilot/V2/Sidebar/QueryCopilotSidebar.tsx
Normal file
57
src/Explorer/QueryCopilot/V2/Sidebar/QueryCopilotSidebar.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
@ -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>
|
||||||
|
`;
|
@ -1,5 +1,5 @@
|
|||||||
import { FeedOptions } from "@azure/cosmos";
|
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 { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection";
|
||||||
import { useDatabases } from "Explorer/useDatabases";
|
import { useDatabases } from "Explorer/useDatabases";
|
||||||
import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";
|
import { QueryCopilotState, useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user