rebranding of inline copilot (#1767)

* rebranding of inline copilot

* rebranding of inline copilot

* rebranding of inline copilot

* fix styling
This commit is contained in:
sunghyunkang1111 2024-03-18 12:15:24 -05:00 committed by GitHub
parent 91d9e27049
commit ac22e88d9c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 497 additions and 311 deletions

View File

@ -49,7 +49,7 @@ export const QueryCopilotFeedbackModal = ({
}; };
return ( return (
<Modal isOpen={showFeedbackModal}> <Modal isOpen={showFeedbackModal} styles={{ main: { borderRadius: 8, maxWidth: 600 } }}>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<Stack style={{ padding: 24 }}> <Stack style={{ padding: 24 }}>
<Stack horizontal horizontalAlign="space-between"> <Stack horizontal horizontalAlign="space-between">
@ -68,9 +68,14 @@ export const QueryCopilotFeedbackModal = ({
rows={3} rows={3}
/> />
<TextField <TextField
styles={{ root: { marginBottom: 14 } }} styles={{
root: { marginBottom: 14 },
fieldGroup: { backgroundColor: "#F3F2F1", borderRadius: 4, borderColor: "#D1D1D1" },
}}
label="Query generated" label="Query generated"
defaultValue={generatedQuery} defaultValue={generatedQuery}
multiline
rows={3}
readOnly readOnly
/> />
<Text style={{ fontSize: 12, marginBottom: 14 }}> <Text style={{ fontSize: 12, marginBottom: 14 }}>

View File

@ -3,6 +3,14 @@
exports[`Query Copilot Feedback Modal snapshot test shoud render and match snapshot 1`] = ` exports[`Query Copilot Feedback Modal snapshot test shoud render and match snapshot 1`] = `
<Modal <Modal
isOpen={true} isOpen={true}
styles={
Object {
"main": Object {
"borderRadius": 8,
"maxWidth": 600,
},
}
}
> >
<form <form
onSubmit={[Function]} onSubmit={[Function]}
@ -67,9 +75,16 @@ exports[`Query Copilot Feedback Modal snapshot test shoud render and match snaps
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="test query" defaultValue="test query"
label="Query generated" label="Query generated"
multiline={true}
readOnly={true} readOnly={true}
rows={3}
styles={ styles={
Object { Object {
"fieldGroup": Object {
"backgroundColor": "#F3F2F1",
"borderColor": "#D1D1D1",
"borderRadius": 4,
},
"root": Object { "root": Object {
"marginBottom": 14, "marginBottom": 14,
}, },
@ -125,6 +140,14 @@ exports[`Query Copilot Feedback Modal snapshot test shoud render and match snaps
exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`] = ` exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`] = `
<Modal <Modal
isOpen={false} isOpen={false}
styles={
Object {
"main": Object {
"borderRadius": 8,
"maxWidth": 600,
},
}
}
> >
<form <form
onSubmit={[Function]} onSubmit={[Function]}
@ -189,9 +212,16 @@ exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`]
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="test query" defaultValue="test query"
label="Query generated" label="Query generated"
multiline={true}
readOnly={true} readOnly={true}
rows={3}
styles={ styles={
Object { Object {
"fieldGroup": Object {
"backgroundColor": "#F3F2F1",
"borderColor": "#D1D1D1",
"borderRadius": 4,
},
"root": Object { "root": Object {
"marginBottom": 14, "marginBottom": 14,
}, },
@ -247,6 +277,14 @@ exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`]
exports[`Query Copilot Feedback Modal snapshot test should close on cancel click 1`] = ` exports[`Query Copilot Feedback Modal snapshot test should close on cancel click 1`] = `
<Modal <Modal
isOpen={false} isOpen={false}
styles={
Object {
"main": Object {
"borderRadius": 8,
"maxWidth": 600,
},
}
}
> >
<form <form
onSubmit={[Function]} onSubmit={[Function]}
@ -311,9 +349,16 @@ exports[`Query Copilot Feedback Modal snapshot test should close on cancel click
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="test query" defaultValue="test query"
label="Query generated" label="Query generated"
multiline={true}
readOnly={true} readOnly={true}
rows={3}
styles={ styles={
Object { Object {
"fieldGroup": Object {
"backgroundColor": "#F3F2F1",
"borderColor": "#D1D1D1",
"borderRadius": 4,
},
"root": Object { "root": Object {
"marginBottom": 14, "marginBottom": 14,
}, },
@ -369,6 +414,14 @@ exports[`Query Copilot Feedback Modal snapshot test should close on cancel click
exports[`Query Copilot Feedback Modal snapshot test should get user unput 1`] = ` exports[`Query Copilot Feedback Modal snapshot test should get user unput 1`] = `
<Modal <Modal
isOpen={false} isOpen={false}
styles={
Object {
"main": Object {
"borderRadius": 8,
"maxWidth": 600,
},
}
}
> >
<form <form
onSubmit={[Function]} onSubmit={[Function]}
@ -433,9 +486,16 @@ exports[`Query Copilot Feedback Modal snapshot test should get user unput 1`] =
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="test query" defaultValue="test query"
label="Query generated" label="Query generated"
multiline={true}
readOnly={true} readOnly={true}
rows={3}
styles={ styles={
Object { Object {
"fieldGroup": Object {
"backgroundColor": "#F3F2F1",
"borderColor": "#D1D1D1",
"borderRadius": 4,
},
"root": Object { "root": Object {
"marginBottom": 14, "marginBottom": 14,
}, },
@ -491,6 +551,14 @@ exports[`Query Copilot Feedback Modal snapshot test should get user unput 1`] =
exports[`Query Copilot Feedback Modal snapshot test should not render dont show again button 1`] = ` exports[`Query Copilot Feedback Modal snapshot test should not render dont show again button 1`] = `
<Modal <Modal
isOpen={false} isOpen={false}
styles={
Object {
"main": Object {
"borderRadius": 8,
"maxWidth": 600,
},
}
}
> >
<form <form
onSubmit={[Function]} onSubmit={[Function]}
@ -555,9 +623,16 @@ exports[`Query Copilot Feedback Modal snapshot test should not render dont show
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="test query" defaultValue="test query"
label="Query generated" label="Query generated"
multiline={true}
readOnly={true} readOnly={true}
rows={3}
styles={ styles={
Object { Object {
"fieldGroup": Object {
"backgroundColor": "#F3F2F1",
"borderColor": "#D1D1D1",
"borderRadius": 4,
},
"root": Object { "root": Object {
"marginBottom": 14, "marginBottom": 14,
}, },
@ -613,6 +688,14 @@ exports[`Query Copilot Feedback Modal snapshot test should not render dont show
exports[`Query Copilot Feedback Modal snapshot test should render dont show again button and check it 1`] = ` exports[`Query Copilot Feedback Modal snapshot test should render dont show again button and check it 1`] = `
<Modal <Modal
isOpen={true} isOpen={true}
styles={
Object {
"main": Object {
"borderRadius": 8,
"maxWidth": 600,
},
}
}
> >
<form <form
onSubmit={[Function]} onSubmit={[Function]}
@ -677,9 +760,16 @@ exports[`Query Copilot Feedback Modal snapshot test should render dont show agai
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="test query" defaultValue="test query"
label="Query generated" label="Query generated"
multiline={true}
readOnly={true} readOnly={true}
rows={3}
styles={ styles={
Object { Object {
"fieldGroup": Object {
"backgroundColor": "#F3F2F1",
"borderColor": "#D1D1D1",
"borderRadius": 4,
},
"root": Object { "root": Object {
"marginBottom": 14, "marginBottom": 14,
}, },
@ -750,6 +840,14 @@ exports[`Query Copilot Feedback Modal snapshot test should render dont show agai
exports[`Query Copilot Feedback Modal snapshot test should submit submission 1`] = ` exports[`Query Copilot Feedback Modal snapshot test should submit submission 1`] = `
<Modal <Modal
isOpen={false} isOpen={false}
styles={
Object {
"main": Object {
"borderRadius": 8,
"maxWidth": 600,
},
}
}
> >
<form <form
onSubmit={[Function]} onSubmit={[Function]}
@ -814,9 +912,16 @@ exports[`Query Copilot Feedback Modal snapshot test should submit submission 1`]
<StyledTextFieldBase <StyledTextFieldBase
defaultValue="test query" defaultValue="test query"
label="Query generated" label="Query generated"
multiline={true}
readOnly={true} readOnly={true}
rows={3}
styles={ styles={
Object { Object {
"fieldGroup": Object {
"backgroundColor": "#F3F2F1",
"borderColor": "#D1D1D1",
"borderRadius": 4,
},
"root": Object { "root": Object {
"marginBottom": 14, "marginBottom": 14,
}, },

View File

@ -11,8 +11,8 @@ import {
Link, Link,
MessageBar, MessageBar,
MessageBarType, MessageBarType,
ProgressIndicator,
Separator, Separator,
Spinner,
Stack, Stack,
TeachingBubble, TeachingBubble,
Text, Text,
@ -36,7 +36,6 @@ import { userContext } from "UserContext";
import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useQueryCopilot } from "hooks/useQueryCopilot";
import React, { useRef, useState } from "react"; import React, { useRef, useState } from "react";
import HintIcon from "../../../images/Hint.svg"; import HintIcon from "../../../images/Hint.svg";
import CopilotIcon from "../../../images/QueryCopilotNewLogo.svg";
import RecentIcon from "../../../images/Recent.svg"; import RecentIcon from "../../../images/Recent.svg";
import errorIcon from "../../../images/close-black.svg"; import errorIcon from "../../../images/close-black.svg";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
@ -215,12 +214,10 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
const generateSQLQueryResponse: GenerateSQLQueryResponse = await response?.json(); const generateSQLQueryResponse: GenerateSQLQueryResponse = await response?.json();
if (response.ok) { if (response.ok) {
if (generateSQLQueryResponse?.sql !== "N/A") { if (generateSQLQueryResponse?.sql !== "N/A") {
let query = `-- **Prompt:** ${userPrompt}\r\n`; let currentGeneratedQuery = `-- **Prompt:** ${userPrompt}\r\n`;
if (generateSQLQueryResponse.explanation) { currentGeneratedQuery += generateSQLQueryResponse.sql;
query += `-- **Explanation of query:** ${generateSQLQueryResponse.explanation}\r\n`; const lastQuery = generatedQuery && query ? `${query}\r\n` : "";
} setQuery(`${lastQuery}${currentGeneratedQuery}`);
query += generateSQLQueryResponse.sql;
setQuery(query);
setGeneratedQuery(generateSQLQueryResponse.sql); setGeneratedQuery(generateSQLQueryResponse.sql);
setGeneratedQueryComments(generateSQLQueryResponse.explanation); setGeneratedQueryComments(generateSQLQueryResponse.explanation);
setShowFeedbackBar(true); setShowFeedbackBar(true);
@ -310,29 +307,24 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
return ( return (
<Stack <Stack
className="copilot-prompt-pane" className="copilot-prompt-pane"
styles={{ root: { backgroundColor: "#FAFAFA", padding: "16px 24px 0px" } }} styles={{ root: { backgroundColor: "#FAFAFA", padding: "8px" } }}
id="copilot-textfield-label" id="copilot-textfield-label"
> >
<Stack horizontal> <Stack
<Image src={CopilotIcon} style={{ width: 24, height: 24 }} alt="Copilot" role="none" /> horizontal
<Text style={{ marginLeft: 8, fontWeight: 600, fontSize: 16 }}>Copilot</Text>
<IconButton
iconProps={{ imageProps: { src: errorIcon } }}
onClick={() => {
toggleCopilot(false);
clearFeedback();
resetMessageStates();
}}
styles={{ styles={{
root: { root: {
marginLeft: "auto !important", width: "100%",
borderWidth: 1,
borderStyle: "solid",
borderColor: "#D1D1D1",
borderRadius: 8,
boxShadow: "0px 4px 8px 0px #00000024",
}, },
}} }}
ariaLabel="Close" >
title="Close copilot" <Stack style={{ width: "100%" }}>
/> <Stack horizontal verticalAlign="center" style={{ padding: "8px 8px 0px 8px" }}>
</Stack>
<Stack horizontal verticalAlign="center">
<TextField <TextField
id="naturalLanguageInput" id="naturalLanguageInput"
value={userPrompt} value={userPrompt}
@ -348,11 +340,38 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
} }
}} }}
style={{ lineHeight: 30 }} style={{ lineHeight: 30 }}
styles={{ root: { width: "95%" }, fieldGroup: { borderRadius: 6 } }} styles={{
root: { width: "100%" },
suffix: {
background: "none",
padding: 0,
},
fieldGroup: {
borderRadius: 4,
borderColor: "#D1D1D1",
"::after": {
border: "inherit",
borderWidth: 2,
borderBottomColor: "#464FEB",
borderRadius: 4,
},
},
}}
disabled={isGeneratingQuery} disabled={isGeneratingQuery}
autoComplete="off" autoComplete="off"
placeholder="Ask a question in natural language and well generate the query for you." placeholder="Ask a question in natural language and well generate the query for you."
aria-labelledby="copilot-textfield-label" aria-labelledby="copilot-textfield-label"
onRenderSuffix={() => {
return (
<IconButton
iconProps={{ iconName: "Send" }}
disabled={isGeneratingQuery || !userPrompt.trim()}
style={{ background: "none" }}
onClick={() => startGenerateQueryProcess()}
aria-label="Send"
/>
);
}}
/> />
{showPromptTeachingBubble && copilotTeachingBubbleVisible && ( {showPromptTeachingBubble && copilotTeachingBubbleVisible && (
<TeachingBubble <TeachingBubble
@ -377,16 +396,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
or write your own query or write your own query
</TeachingBubble> </TeachingBubble>
)} )}
<IconButton
iconProps={{ iconName: "Send" }}
disabled={isGeneratingQuery || !userPrompt.trim()}
style={{ marginLeft: 8 }}
onClick={() => startGenerateQueryProcess()}
aria-label="Send"
/>
<div role="alert" aria-label={getAriaLabel()}>
{isGeneratingQuery && <Spinner style={{ marginLeft: 8 }} />}
</div>
{showSamplePrompts && ( {showSamplePrompts && (
<Callout <Callout
styles={{ root: { minWidth: 400, maxWidth: "70vw" } }} styles={{ root: { minWidth: 400, maxWidth: "70vw" } }}
@ -488,8 +497,9 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
</Callout> </Callout>
)} )}
</Stack> </Stack>
{!isGeneratingQuery && (
<Stack style={{ margin: "8px 0" }}> <Stack style={{ padding: 8 }}>
{!showFeedbackBar && (
<Text style={{ fontSize: 12 }}> <Text style={{ fontSize: 12 }}>
AI-generated content can have mistakes. Make sure it&apos;s accurate and appropriate before using it.{" "} AI-generated content can have mistakes. Make sure it&apos;s accurate and appropriate before using it.{" "}
<Link href="https://aka.ms/cdb-copilot-preview-terms" target="_blank" style={{ color: "#0072D4" }}> <Link href="https://aka.ms/cdb-copilot-preview-terms" target="_blank" style={{ color: "#0072D4" }}>
@ -505,8 +515,8 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
messageBarType={MessageBarType.info} messageBarType={MessageBarType.info}
styles={{ root: { backgroundColor: "#F0F6FF" }, icon: { color: "#015CDA" } }} styles={{ root: { backgroundColor: "#F0F6FF" }, icon: { color: "#015CDA" } }}
> >
We were unable to generate a query based upon the prompt provided. Please modify the prompt and try again. We were unable to generate a query based upon the prompt provided. Please modify the prompt and
For examples of how to write a good prompt, please read try again. For examples of how to write a good prompt, please read
<Link href="https://aka.ms/cdb-copilot-writing" target="_blank"> <Link href="https://aka.ms/cdb-copilot-writing" target="_blank">
this article. this article.
</Link>{" "} </Link>{" "}
@ -517,21 +527,27 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
</MessageBar> </MessageBar>
)} )}
</Text> </Text>
</Stack> )}
{showFeedbackBar && ( {showFeedbackBar && (
<Stack <Stack horizontal verticalAlign="center" style={{ maxHeight: 20 }}>
style={{ backgroundColor: "#FFF8F0", padding: "2px 8px", minHeight: 32 }}
horizontal
verticalAlign="center"
>
{userContext.feedbackPolicies?.policyAllowFeedback && ( {userContext.feedbackPolicies?.policyAllowFeedback && (
<Stack horizontal verticalAlign="center"> <Stack horizontal verticalAlign="center">
<Text style={{ fontWeight: 600, fontSize: 12 }}>Provide feedback on the query generated</Text> <Text style={{ fontSize: 12 }}>Provide feedback</Text>
{showCallout && !hideFeedbackModalForLikedQueries && ( {showCallout && !hideFeedbackModalForLikedQueries && (
<Callout <Callout
role="status" role="status"
style={{ padding: 8 }} style={{ padding: "6px 12px" }}
styles={{
root: {
borderRadius: 8,
},
beakCurtain: {
borderRadius: 8,
},
calloutMain: {
borderRadius: 8,
},
}}
target="#likeBtn" target="#likeBtn"
onDismiss={() => { onDismiss={() => {
setShowCallout(false); setShowCallout(false);
@ -565,7 +581,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
)} )}
<IconButton <IconButton
id="likeBtn" id="likeBtn"
style={{ marginLeft: 20 }} style={{ marginLeft: 10 }}
aria-label="Like" aria-label="Like"
role="toggle" role="toggle"
iconProps={{ iconName: likeQuery === true ? "LikeSolid" : "Like" }} iconProps={{ iconName: likeQuery === true ? "LikeSolid" : "Like" }}
@ -584,7 +600,7 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}} }}
/> />
<IconButton <IconButton
style={{ margin: "0 10px" }} style={{ margin: "0 4px" }}
role="toggle" role="toggle"
aria-label="Dislike" aria-label="Dislike"
iconProps={{ iconName: dislikeQuery === true ? "DislikeSolid" : "Dislike" }} iconProps={{ iconName: dislikeQuery === true ? "DislikeSolid" : "Dislike" }}
@ -601,16 +617,30 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
}} }}
/> />
<span role="status" style={{ position: "absolute", left: "-9999px" }} id="likeStatus"></span> <span role="status" style={{ position: "absolute", left: "-9999px" }} id="likeStatus"></span>
<Separator vertical style={{ color: "#EDEBE9" }} /> <Separator
vertical
styles={{
root: {
"::after": {
backgroundColor: "#767676",
},
},
}}
/>
</Stack> </Stack>
)} )}
<CommandBarButton <CommandBarButton
className="copyQuery" className="copyQuery"
onClick={copyGeneratedCode} onClick={copyGeneratedCode}
iconProps={{ iconName: "Copy" }} iconProps={{ iconName: "Copy" }}
style={{ margin: "0 10px", backgroundColor: "#FFF8F0", transition: "background-color 0.3s ease" }} style={{ fontSize: 12, transition: "background-color 0.3s ease", height: "100%" }}
styles={{
root: {
backgroundColor: "inherit",
},
}}
> >
Copy query Copy code
</CommandBarButton> </CommandBarButton>
<CommandBarButton <CommandBarButton
className="deleteQuery" className="deleteQuery"
@ -618,12 +648,58 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
setShowDeletePopup(true); setShowDeletePopup(true);
}} }}
iconProps={{ iconName: "Delete" }} iconProps={{ iconName: "Delete" }}
style={{ margin: "0 10px", backgroundColor: "#FFF8F0", transition: "background-color 0.3s ease" }} style={{ fontSize: 12, transition: "background-color 0.3s ease", height: "100%" }}
styles={{
root: {
backgroundColor: "inherit",
},
}}
> >
Delete query Clear editor
</CommandBarButton> </CommandBarButton>
</Stack> </Stack>
)} )}
</Stack>
)}
{isGeneratingQuery && (
<ProgressIndicator
label="Thinking..."
ariaLabel={getAriaLabel()}
barHeight={4}
styles={{
root: {
fontSize: 12,
width: "100%",
bottom: 0,
},
itemName: {
padding: "0px 8px",
},
itemProgress: {
borderBottomLeftRadius: 8,
borderBottomRightRadius: 8,
padding: 0,
},
progressBar: {
backgroundImage:
"linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgb(24, 90, 189) 35%, rgb(71, 207, 250) 70%, rgb(180, 124, 248) 92%, rgba(0, 0, 0, 0))",
animationDuration: "5s",
},
}}
/>
)}
</Stack>
<IconButton
iconProps={{ imageProps: { src: errorIcon } }}
onClick={() => {
toggleCopilot(false);
clearFeedback();
resetMessageStates();
}}
ariaLabel="Close"
title="Close copilot"
/>
</Stack>
{isSamplePromptsOpen && <SamplePrompts sampleProps={sampleProps} />} {isSamplePromptsOpen && <SamplePrompts sampleProps={sampleProps} />}
{query !== "" && query.trim().length !== 0 && ( {query !== "" && query.trim().length !== 0 && (
<DeletePopup <DeletePopup