mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-29 05:41:40 +00:00
Compare commits
9 Commits
2262594
...
update_cop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc63ade6c6 | ||
|
|
7ec5290293 | ||
|
|
4005128211 | ||
|
|
38d13cc74e | ||
|
|
4ab93a5a32 | ||
|
|
44e25c0769 | ||
|
|
8ea8f0230f | ||
|
|
655b998b84 | ||
|
|
9e2f6a9c89 |
@@ -230,7 +230,7 @@ input::-webkit-inner-spin-button {
|
|||||||
.advanced-options-panel .advanced-options .select .select-options-link {
|
.advanced-options-panel .advanced-options .select .select-options-link {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
outline: none;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.query-panel .row .column-headers .Field {
|
.query-panel .row .column-headers .Field {
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ export const TableEntity: FunctionComponent<TableEntityProps> = ({
|
|||||||
/>
|
/>
|
||||||
{!isEntityValueDisable && (
|
{!isEntityValueDisable && (
|
||||||
<TooltipHost content="Edit property" id="editTooltip">
|
<TooltipHost content="Edit property" id="editTooltip">
|
||||||
<div tabIndex={0}>
|
<div>
|
||||||
<Image
|
<Image
|
||||||
{...imageProps}
|
{...imageProps}
|
||||||
src={EditIcon}
|
src={EditIcon}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
|
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
|
||||||
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import AddCollectionIcon from "../../images/AddCollection.svg";
|
import AddCollectionIcon from "../../images/AddCollection.svg";
|
||||||
@@ -146,7 +148,10 @@ export const createSampleCollectionContextMenuButton = (): TreeNodeMenuItem[] =>
|
|||||||
if (userContext.apiType === "SQL") {
|
if (userContext.apiType === "SQL") {
|
||||||
items.push({
|
items.push({
|
||||||
iconSrc: AddSqlQueryIcon,
|
iconSrc: AddSqlQueryIcon,
|
||||||
onClick: () => useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot),
|
onClick: () => {
|
||||||
|
useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot);
|
||||||
|
traceOpen(Action.OpenQueryCopilotFromNewQuery, { apiType: userContext.apiType });
|
||||||
|
},
|
||||||
label: "New SQL Query",
|
label: "New SQL Query",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
|
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
|
||||||
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
import { ReactTabKind, useTabs } from "hooks/useTabs";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import AddCollectionIcon from "../../../../images/AddCollection.svg";
|
import AddCollectionIcon from "../../../../images/AddCollection.svg";
|
||||||
@@ -326,6 +328,7 @@ function createNewSQLQueryButton(selectedNodeState: SelectedNodeState): CommandB
|
|||||||
onCommandClick: () => {
|
onCommandClick: () => {
|
||||||
if (useSelectedNode.getState().isQueryCopilotCollectionSelected()) {
|
if (useSelectedNode.getState().isQueryCopilotCollectionSelected()) {
|
||||||
useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot);
|
useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot);
|
||||||
|
traceOpen(Action.OpenQueryCopilotFromNewQuery, { apiType: userContext.apiType });
|
||||||
} else {
|
} else {
|
||||||
const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection();
|
const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection();
|
||||||
selectedCollection && selectedCollection.onNewQueryClick(selectedCollection);
|
selectedCollection && selectedCollection.onNewQueryClick(selectedCollection);
|
||||||
|
|||||||
@@ -112,6 +112,9 @@
|
|||||||
margin-top: 28px;
|
margin-top: 28px;
|
||||||
margin-left: 4px !important;
|
margin-left: 4px !important;
|
||||||
}
|
}
|
||||||
|
.addRemoveIcon [alt="editEntity"]:focus,.addRemoveIconLabel [alt="editEntity"]:focus{
|
||||||
|
border:1px dashed #605E5C
|
||||||
|
}
|
||||||
.addNewParamStyle {
|
.addNewParamStyle {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-left: 5px !important;
|
margin-left: 5px !important;
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export const QueryCopilotFeedbackModal: React.FC = (): JSX.Element => {
|
|||||||
<Text style={{ fontSize: 12, marginBottom: 14 }}>
|
<Text style={{ fontSize: 12, marginBottom: 14 }}>
|
||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your
|
||||||
organization will be able to view and manage your feedback data.{" "}
|
organization will be able to view and manage your feedback data.{" "}
|
||||||
<Link href="" target="_blank">
|
<Link href="https://privacy.microsoft.com/privacystatement" target="_blank">
|
||||||
Privacy statement
|
Privacy statement
|
||||||
</Link>
|
</Link>
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
|
|||||||
<Text>
|
<Text>
|
||||||
Ask Copilot to generate a query by describing the query in your words.
|
Ask Copilot to generate a query by describing the query in your words.
|
||||||
<br />
|
<br />
|
||||||
<Link href="">Learn more</Link>
|
<Link href="http://aka.ms/cdb-copilot-learn-more">Learn more</Link>
|
||||||
</Text>
|
</Text>
|
||||||
</Stack.Item>
|
</Stack.Item>
|
||||||
<Stack.Item align="center" className="text">
|
<Stack.Item align="center" className="text">
|
||||||
@@ -78,7 +78,7 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
|
|||||||
<Text>
|
<Text>
|
||||||
AI-generated content can have mistakes. Make sure it’s accurate and appropriate before using it.
|
AI-generated content can have mistakes. Make sure it’s accurate and appropriate before using it.
|
||||||
<br />
|
<br />
|
||||||
<Link href="">Read preview terms</Link>
|
<Link href="http://aka.ms/cdb-copilot-preview-terms">Read preview terms</Link>
|
||||||
</Text>
|
</Text>
|
||||||
</Stack.Item>
|
</Stack.Item>
|
||||||
<Stack.Item align="center" className="text">
|
<Stack.Item align="center" className="text">
|
||||||
@@ -96,7 +96,7 @@ export const WelcomeModal = ({ visible }: { visible: boolean }): JSX.Element =>
|
|||||||
<Text>
|
<Text>
|
||||||
Copilot is setup on a sample database we have configured for you at no cost
|
Copilot is setup on a sample database we have configured for you at no cost
|
||||||
<br />
|
<br />
|
||||||
<Link href="">Learn more</Link>
|
<Link href="http://aka.ms/cdb-copilot-learn-more">Learn more</Link>
|
||||||
</Text>
|
</Text>
|
||||||
</Stack.Item>
|
</Stack.Item>
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ exports[`Query Copilot Feedback Modal snapshot test shoud render and match snaps
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -274,7 +274,7 @@ exports[`Query Copilot Feedback Modal snapshot test should cancel submission 1`]
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -427,7 +427,7 @@ exports[`Query Copilot Feedback Modal snapshot test should close on cancel click
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -580,7 +580,7 @@ exports[`Query Copilot Feedback Modal snapshot test should get user unput 1`] =
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -733,7 +733,7 @@ exports[`Query Copilot Feedback Modal snapshot test should not render dont show
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -886,7 +886,7 @@ exports[`Query Copilot Feedback Modal snapshot test should record user contact c
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -1039,7 +1039,7 @@ exports[`Query Copilot Feedback Modal snapshot test should record user contact c
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -1192,7 +1192,7 @@ exports[`Query Copilot Feedback Modal snapshot test should render dont show agai
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
@@ -1360,7 +1360,7 @@ exports[`Query Copilot Feedback Modal snapshot test should submit submission 1`]
|
|||||||
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
By pressing submit, your feedback will be used to improve Microsoft products and services. IT admins for your organization will be able to view and manage your feedback data.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="https://privacy.microsoft.com/privacystatement"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Privacy statement
|
Privacy statement
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
|
|||||||
Ask Copilot to generate a query by describing the query in your words.
|
Ask Copilot to generate a query by describing the query in your words.
|
||||||
<br />
|
<br />
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="http://aka.ms/cdb-copilot-learn-more"
|
||||||
>
|
>
|
||||||
Learn more
|
Learn more
|
||||||
</StyledLinkBase>
|
</StyledLinkBase>
|
||||||
@@ -133,7 +133,7 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
|
|||||||
AI-generated content can have mistakes. Make sure it’s accurate and appropriate before using it.
|
AI-generated content can have mistakes. Make sure it’s accurate and appropriate before using it.
|
||||||
<br />
|
<br />
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="http://aka.ms/cdb-copilot-preview-terms"
|
||||||
>
|
>
|
||||||
Read preview terms
|
Read preview terms
|
||||||
</StyledLinkBase>
|
</StyledLinkBase>
|
||||||
@@ -169,7 +169,7 @@ exports[`Query Copilot Welcome Modal snapshot test should render when isOpen is
|
|||||||
Copilot is setup on a sample database we have configured for you at no cost
|
Copilot is setup on a sample database we have configured for you at no cost
|
||||||
<br />
|
<br />
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="http://aka.ms/cdb-copilot-learn-more"
|
||||||
>
|
>
|
||||||
Learn more
|
Learn more
|
||||||
</StyledLinkBase>
|
</StyledLinkBase>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
TextField,
|
TextField,
|
||||||
} from "@fluentui/react";
|
} from "@fluentui/react";
|
||||||
import { useBoolean } from "@fluentui/react-hooks";
|
import { useBoolean } from "@fluentui/react-hooks";
|
||||||
import { QueryCopilotSampleContainerId, QueryCopilotSampleContainerSchema } from "Common/Constants";
|
import { JunoEndpoints, QueryCopilotSampleContainerId, QueryCopilotSampleContainerSchema } from "Common/Constants";
|
||||||
import { getErrorMessage, handleError } from "Common/ErrorHandlingUtils";
|
import { getErrorMessage, handleError } from "Common/ErrorHandlingUtils";
|
||||||
import { shouldEnableCrossPartitionKey } from "Common/HeadersUtility";
|
import { shouldEnableCrossPartitionKey } from "Common/HeadersUtility";
|
||||||
import { MinimalQueryIterator } from "Common/IteratorUtilities";
|
import { MinimalQueryIterator } from "Common/IteratorUtilities";
|
||||||
@@ -34,6 +34,8 @@ 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/SamplePrompts/SamplePrompts";
|
||||||
import { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection";
|
import { QueryResultSection } from "Explorer/Tabs/QueryTab/QueryResultSection";
|
||||||
|
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||||
|
import { traceFailure, traceStart, traceSuccess } from "Shared/Telemetry/TelemetryProcessor";
|
||||||
import { userContext } from "UserContext";
|
import { userContext } from "UserContext";
|
||||||
import { queryPagesUntilContentPresent } from "Utils/QueryUtils";
|
import { queryPagesUntilContentPresent } from "Utils/QueryUtils";
|
||||||
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
@@ -78,6 +80,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
const hideFeedbackModalForLikedQueries = useQueryCopilot((state) => state.hideFeedbackModalForLikedQueries);
|
const hideFeedbackModalForLikedQueries = useQueryCopilot((state) => state.hideFeedbackModalForLikedQueries);
|
||||||
const [userPrompt, setUserPrompt] = useState<string>(initialInput || "");
|
const [userPrompt, setUserPrompt] = useState<string>(initialInput || "");
|
||||||
const [generatedQuery, setGeneratedQuery] = useState<string>("");
|
const [generatedQuery, setGeneratedQuery] = useState<string>("");
|
||||||
|
const [generatedQueryComments, setGeneratedQueryComments] = useState<string>("");
|
||||||
const [query, setQuery] = useState<string>("");
|
const [query, setQuery] = useState<string>("");
|
||||||
const [selectedQuery, setSelectedQuery] = useState<string>("");
|
const [selectedQuery, setSelectedQuery] = useState<string>("");
|
||||||
const [isGeneratingQuery, setIsGeneratingQuery] = useState<boolean>(false);
|
const [isGeneratingQuery, setIsGeneratingQuery] = useState<boolean>(false);
|
||||||
@@ -170,10 +173,12 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
userPrompt: userPrompt,
|
userPrompt: userPrompt,
|
||||||
};
|
};
|
||||||
setShowDeletePopup(false);
|
setShowDeletePopup(false);
|
||||||
const response = await fetch("https://copilotorchestrater.azurewebsites.net/generateSQLQuery", {
|
useQueryCopilot.getState().refreshCorrelationId();
|
||||||
|
const response = await fetch(`${JunoEndpoints.Prod}/generateSQLQuery`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
|
"x-ms-correlationid": useQueryCopilot.getState().correlationId,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
});
|
});
|
||||||
@@ -188,6 +193,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
query += generateSQLQueryResponse.sql;
|
query += generateSQLQueryResponse.sql;
|
||||||
setQuery(query);
|
setQuery(query);
|
||||||
setGeneratedQuery(generateSQLQueryResponse.sql);
|
setGeneratedQuery(generateSQLQueryResponse.sql);
|
||||||
|
setGeneratedQueryComments(generateSQLQueryResponse.explanation);
|
||||||
setShowErrorMessageBar(false);
|
setShowErrorMessageBar(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -208,6 +214,13 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onExecuteQueryClick = async (): Promise<void> => {
|
const onExecuteQueryClick = async (): Promise<void> => {
|
||||||
|
traceStart(Action.ExecuteQueryGeneratedFromQueryCopilot, {
|
||||||
|
correlationId: useQueryCopilot.getState().correlationId,
|
||||||
|
userPrompt: userPrompt,
|
||||||
|
generatedQuery: generatedQuery,
|
||||||
|
generatedQueryComments: generatedQueryComments,
|
||||||
|
executedQuery: selectedQuery || query,
|
||||||
|
});
|
||||||
const queryToExecute = selectedQuery || query;
|
const queryToExecute = selectedQuery || query;
|
||||||
const queryIterator = querySampleDocuments(queryToExecute, {
|
const queryIterator = querySampleDocuments(queryToExecute, {
|
||||||
enableCrossPartitionQuery: shouldEnableCrossPartitionKey(),
|
enableCrossPartitionQuery: shouldEnableCrossPartitionKey(),
|
||||||
@@ -233,8 +246,15 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
setQueryResults(queryResults);
|
setQueryResults(queryResults);
|
||||||
setErrorMessage("");
|
setErrorMessage("");
|
||||||
setShowErrorMessageBar(false);
|
setShowErrorMessageBar(false);
|
||||||
|
traceSuccess(Action.ExecuteQueryGeneratedFromQueryCopilot, {
|
||||||
|
correlationId: useQueryCopilot.getState().correlationId,
|
||||||
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = getErrorMessage(error);
|
const errorMessage = getErrorMessage(error);
|
||||||
|
traceFailure(Action.ExecuteQueryGeneratedFromQueryCopilot, {
|
||||||
|
correlationId: useQueryCopilot.getState().correlationId,
|
||||||
|
errorMessage: errorMessage,
|
||||||
|
});
|
||||||
setErrorMessage(errorMessage);
|
setErrorMessage(errorMessage);
|
||||||
handleError(errorMessage, "executeQueryCopilotTab");
|
handleError(errorMessage, "executeQueryCopilotTab");
|
||||||
useTabs.getState().setIsQueryErrorThrown(true);
|
useTabs.getState().setIsQueryErrorThrown(true);
|
||||||
@@ -297,6 +317,12 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
setShowCallout(false);
|
setShowCallout(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const startGenerateQueryProcess = () => {
|
||||||
|
updateHistories();
|
||||||
|
generateSQLQuery();
|
||||||
|
resetButtonState();
|
||||||
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
useCommandBar.getState().setContextButtons(getCommandbarButtons());
|
useCommandBar.getState().setContextButtons(getCommandbarButtons());
|
||||||
}, [query, selectedQuery]);
|
}, [query, selectedQuery]);
|
||||||
@@ -325,6 +351,11 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
inputEdited.current = true;
|
inputEdited.current = true;
|
||||||
setShowSamplePrompts(true);
|
setShowSamplePrompts(true);
|
||||||
}}
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
startGenerateQueryProcess();
|
||||||
|
}
|
||||||
|
}}
|
||||||
style={{ lineHeight: 30 }}
|
style={{ lineHeight: 30 }}
|
||||||
styles={{ root: { width: "95%" } }}
|
styles={{ root: { width: "95%" } }}
|
||||||
disabled={isGeneratingQuery}
|
disabled={isGeneratingQuery}
|
||||||
@@ -357,11 +388,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
iconProps={{ iconName: "Send" }}
|
iconProps={{ iconName: "Send" }}
|
||||||
disabled={isGeneratingQuery || !userPrompt.trim()}
|
disabled={isGeneratingQuery || !userPrompt.trim()}
|
||||||
style={{ marginLeft: 8 }}
|
style={{ marginLeft: 8 }}
|
||||||
onClick={() => {
|
onClick={() => startGenerateQueryProcess()}
|
||||||
updateHistories();
|
|
||||||
generateSQLQuery();
|
|
||||||
resetButtonState();
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
{isGeneratingQuery && <Spinner style={{ marginLeft: 8 }} />}
|
{isGeneratingQuery && <Spinner style={{ marginLeft: 8 }} />}
|
||||||
{showSamplePrompts && (
|
{showSamplePrompts && (
|
||||||
@@ -453,7 +480,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Learn about{" "}
|
Learn about{" "}
|
||||||
<Link target="_blank" href="">
|
<Link target="_blank" href="http://aka.ms/cdb-copilot-writing">
|
||||||
writing effective prompts
|
writing effective prompts
|
||||||
</Link>
|
</Link>
|
||||||
</Text>
|
</Text>
|
||||||
@@ -467,7 +494,7 @@ export const QueryCopilotTab: React.FC<QueryCopilotTabProps> = ({
|
|||||||
<Stack style={{ marginTop: 8, marginBottom: 24 }}>
|
<Stack style={{ marginTop: 8, marginBottom: 24 }}>
|
||||||
<Text style={{ fontSize: 12 }}>
|
<Text style={{ fontSize: 12 }}>
|
||||||
AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.{" "}
|
AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.{" "}
|
||||||
<Link href="" target="_blank">
|
<Link href="http://aka.ms/cdb-copilot-preview-terms" target="_blank">
|
||||||
Read preview terms
|
Read preview terms
|
||||||
</Link>
|
</Link>
|
||||||
{showErrorMessageBar && (
|
{showErrorMessageBar && (
|
||||||
|
|||||||
225
src/Explorer/QueryCopilot/QueryCopilotUtilities.test.tsx
Normal file
225
src/Explorer/QueryCopilot/QueryCopilotUtilities.test.tsx
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
import { FeedOptions } from "@azure/cosmos";
|
||||||
|
import { QueryCopilotSampleContainerSchema } from "Common/Constants";
|
||||||
|
import { handleError } from "Common/ErrorHandlingUtils";
|
||||||
|
import { sampleDataClient } from "Common/SampleDataClient";
|
||||||
|
import * as commonUtils from "Common/dataAccess/queryDocuments";
|
||||||
|
import DocumentId from "Explorer/Tree/DocumentId";
|
||||||
|
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
|
import { querySampleDocuments, readSampleDocument, submitFeedback } from "./QueryCopilotUtilities";
|
||||||
|
jest.mock("Explorer/Tree/DocumentId", () => {
|
||||||
|
return jest.fn().mockImplementation(() => {
|
||||||
|
return {
|
||||||
|
id: jest.fn(),
|
||||||
|
loadDocument: jest.fn(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
jest.mock("Utils/NotificationConsoleUtils", () => ({
|
||||||
|
logConsoleProgress: jest.fn(),
|
||||||
|
logConsoleError: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("@azure/cosmos", () => ({
|
||||||
|
FeedOptions: jest.fn(),
|
||||||
|
QueryIterator: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("Common/ErrorHandlingUtils", () => ({
|
||||||
|
handleError: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("Utils/NotificationConsoleUtils", () => ({
|
||||||
|
logConsoleProgress: jest.fn().mockReturnValue((): void => undefined),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("Common/dataAccess/queryDocuments", () => ({
|
||||||
|
getCommonQueryOptions: jest.fn((options) => options),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock("Common/SampleDataClient");
|
||||||
|
|
||||||
|
jest.mock("node-fetch");
|
||||||
|
|
||||||
|
describe("QueryCopilotUtilities", () => {
|
||||||
|
beforeEach(() => jest.clearAllMocks());
|
||||||
|
describe("submitFeedback", () => {
|
||||||
|
const payload = {
|
||||||
|
like: "like",
|
||||||
|
generatedSql: "GeneratedQuery",
|
||||||
|
userPrompt: "UserPrompt",
|
||||||
|
description: "Description",
|
||||||
|
contact: "Contact",
|
||||||
|
containerSchema: QueryCopilotSampleContainerSchema,
|
||||||
|
};
|
||||||
|
|
||||||
|
it("should call fetch with the payload with like", async () => {
|
||||||
|
const mockFetch = jest.fn().mockResolvedValueOnce({});
|
||||||
|
|
||||||
|
globalThis.fetch = mockFetch;
|
||||||
|
useQueryCopilot.getState().refreshCorrelationId();
|
||||||
|
|
||||||
|
await submitFeedback({
|
||||||
|
likeQuery: true,
|
||||||
|
generatedQuery: "GeneratedQuery",
|
||||||
|
userPrompt: "UserPrompt",
|
||||||
|
description: "Description",
|
||||||
|
contact: "Contact",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockFetch).toHaveBeenCalledWith(
|
||||||
|
"https://copilotorchestrater.azurewebsites.net/feedback",
|
||||||
|
expect.objectContaining({
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
"x-ms-correlationid": useQueryCopilot.getState().correlationId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const actualBody = JSON.parse(mockFetch.mock.calls[0][1].body);
|
||||||
|
expect(actualBody).toEqual(payload);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call fetch with the payload with unlike and empty parameters", async () => {
|
||||||
|
payload.like = "dislike";
|
||||||
|
payload.description = "";
|
||||||
|
payload.contact = "";
|
||||||
|
const mockFetch = jest.fn().mockResolvedValueOnce({});
|
||||||
|
|
||||||
|
globalThis.fetch = mockFetch;
|
||||||
|
useQueryCopilot.getState().refreshCorrelationId();
|
||||||
|
|
||||||
|
await submitFeedback({
|
||||||
|
likeQuery: false,
|
||||||
|
generatedQuery: "GeneratedQuery",
|
||||||
|
userPrompt: "UserPrompt",
|
||||||
|
description: undefined,
|
||||||
|
contact: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(mockFetch).toHaveBeenCalledWith(
|
||||||
|
"https://copilotorchestrater.azurewebsites.net/feedback",
|
||||||
|
expect.objectContaining({
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"content-type": "application/json",
|
||||||
|
"x-ms-correlationid": useQueryCopilot.getState().correlationId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const actualBody = JSON.parse(mockFetch.mock.calls[0][1].body);
|
||||||
|
expect(actualBody).toEqual(payload);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle errors and call handleError", async () => {
|
||||||
|
globalThis.fetch = jest.fn().mockRejectedValueOnce(new Error("Mock error"));
|
||||||
|
|
||||||
|
await submitFeedback({
|
||||||
|
likeQuery: true,
|
||||||
|
generatedQuery: "GeneratedQuery",
|
||||||
|
userPrompt: "UserPrompt",
|
||||||
|
description: "Description",
|
||||||
|
contact: "Contact",
|
||||||
|
}).catch((error) => {
|
||||||
|
expect(error.message).toEqual("Mock error");
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(handleError).toHaveBeenCalledWith(new Error("Mock error"), expect.any(String));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("querySampleDocuments", () => {
|
||||||
|
(sampleDataClient as jest.Mock).mockReturnValue({
|
||||||
|
database: jest.fn().mockReturnValue({
|
||||||
|
container: jest.fn().mockReturnValue({
|
||||||
|
items: {
|
||||||
|
query: jest.fn().mockReturnValue([]),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
it("calls getCommonQueryOptions with the provided options", () => {
|
||||||
|
const query = "sample query";
|
||||||
|
const options: FeedOptions = { maxItemCount: 10 };
|
||||||
|
|
||||||
|
querySampleDocuments(query, options);
|
||||||
|
|
||||||
|
expect(commonUtils.getCommonQueryOptions).toHaveBeenCalledWith(options);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns the result of items.query method", () => {
|
||||||
|
const query = "sample query";
|
||||||
|
const options: FeedOptions = { maxItemCount: 10 };
|
||||||
|
const mockResult = [
|
||||||
|
{ id: 1, name: "Document 1" },
|
||||||
|
{ id: 2, name: "Document 2" },
|
||||||
|
];
|
||||||
|
|
||||||
|
// Mock the items.query method to return the mockResult
|
||||||
|
(sampleDataClient().database("CopilotSampleDb").container("SampleContainer").items
|
||||||
|
.query as jest.Mock).mockReturnValue(mockResult);
|
||||||
|
|
||||||
|
const result = querySampleDocuments(query, options);
|
||||||
|
|
||||||
|
expect(result).toEqual(mockResult);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("readSampleDocument", () => {
|
||||||
|
it("should call the read method with the correct parameters", async () => {
|
||||||
|
(sampleDataClient as jest.Mock).mockReturnValue({
|
||||||
|
database: jest.fn().mockReturnValue({
|
||||||
|
container: jest.fn().mockReturnValue({
|
||||||
|
item: jest.fn().mockReturnValue({
|
||||||
|
read: jest.fn().mockResolvedValue({
|
||||||
|
resource: {},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const documentId = new DocumentId(null, "DocumentId", []);
|
||||||
|
const expectedResponse = {};
|
||||||
|
|
||||||
|
const result = await readSampleDocument(documentId);
|
||||||
|
|
||||||
|
expect(sampleDataClient).toHaveBeenCalled();
|
||||||
|
expect(sampleDataClient().database).toHaveBeenCalledWith("CopilotSampleDb");
|
||||||
|
expect(sampleDataClient().database("CopilotSampleDb").container).toHaveBeenCalledWith("SampleContainer");
|
||||||
|
expect(
|
||||||
|
sampleDataClient().database("CopilotSampleDb").container("SampleContainer").item("DocumentId", undefined).read
|
||||||
|
).toHaveBeenCalled();
|
||||||
|
expect(result).toEqual(expectedResponse);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle an error and re-throw it", async () => {
|
||||||
|
(sampleDataClient as jest.Mock).mockReturnValue({
|
||||||
|
database: jest.fn().mockReturnValue({
|
||||||
|
container: jest.fn().mockReturnValue({
|
||||||
|
item: jest.fn().mockReturnValue({
|
||||||
|
read: jest.fn().mockRejectedValue(new Error("Mock error")),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const errorMock = new Error("Mock error");
|
||||||
|
const documentId = new DocumentId(null, "DocumentId", []);
|
||||||
|
|
||||||
|
await expect(readSampleDocument(documentId)).rejects.toStrictEqual(errorMock);
|
||||||
|
|
||||||
|
expect(sampleDataClient).toHaveBeenCalled();
|
||||||
|
expect(sampleDataClient().database).toHaveBeenCalledWith("CopilotSampleDb");
|
||||||
|
expect(sampleDataClient().database("CopilotSampleDb").container).toHaveBeenCalledWith("SampleContainer");
|
||||||
|
expect(
|
||||||
|
sampleDataClient().database("CopilotSampleDb").container("SampleContainer").item("DocumentId", undefined).read
|
||||||
|
).toHaveBeenCalled();
|
||||||
|
expect(handleError).toHaveBeenCalledWith(errorMock, "ReadDocument", expect.any(String));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { FeedOptions, Item, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
import { FeedOptions, Item, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
|
||||||
import {
|
import {
|
||||||
|
JunoEndpoints,
|
||||||
QueryCopilotSampleContainerId,
|
QueryCopilotSampleContainerId,
|
||||||
QueryCopilotSampleContainerSchema,
|
QueryCopilotSampleContainerSchema,
|
||||||
QueryCopilotSampleDatabaseId,
|
QueryCopilotSampleDatabaseId,
|
||||||
@@ -10,6 +11,7 @@ import { getPartitionKeyValue } from "Common/dataAccess/getPartitionKeyValue";
|
|||||||
import { getCommonQueryOptions } from "Common/dataAccess/queryDocuments";
|
import { getCommonQueryOptions } from "Common/dataAccess/queryDocuments";
|
||||||
import DocumentId from "Explorer/Tree/DocumentId";
|
import DocumentId from "Explorer/Tree/DocumentId";
|
||||||
import { logConsoleProgress } from "Utils/NotificationConsoleUtils";
|
import { logConsoleProgress } from "Utils/NotificationConsoleUtils";
|
||||||
|
import { useQueryCopilot } from "hooks/useQueryCopilot";
|
||||||
|
|
||||||
interface FeedbackParams {
|
interface FeedbackParams {
|
||||||
likeQuery: boolean;
|
likeQuery: boolean;
|
||||||
@@ -31,10 +33,11 @@ export const submitFeedback = async (params: FeedbackParams): Promise<void> => {
|
|||||||
contact: contact || "",
|
contact: contact || "",
|
||||||
};
|
};
|
||||||
|
|
||||||
await fetch("https://copilotorchestrater.azurewebsites.net/feedback", {
|
await fetch(`${JunoEndpoints.Prod}/feedback`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
|
"x-ms-correlationid": useQueryCopilot.getState().correlationId,
|
||||||
},
|
},
|
||||||
body: JSON.stringify(payload),
|
body: JSON.stringify(payload),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ exports[`Query copilot tab snapshot test should render with initial input 1`] =
|
|||||||
id="naturalLanguageInput"
|
id="naturalLanguageInput"
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
|
onKeyDown={[Function]}
|
||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"lineHeight": 30,
|
"lineHeight": 30,
|
||||||
@@ -101,7 +102,7 @@ exports[`Query copilot tab snapshot test should render with initial input 1`] =
|
|||||||
AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.
|
AI-generated content can have mistakes. Make sure it's accurate and appropriate before using it.
|
||||||
|
|
||||||
<StyledLinkBase
|
<StyledLinkBase
|
||||||
href=""
|
href="http://aka.ms/cdb-copilot-preview-terms"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
Read preview terms
|
Read preview terms
|
||||||
|
|||||||
@@ -97,6 +97,12 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
() => this.setState({}),
|
() => this.setState({}),
|
||||||
(state) => state.showResetPasswordBubble
|
(state) => state.showResetPasswordBubble
|
||||||
),
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dispose: useDatabases.subscribe(
|
||||||
|
() => this.setState({}),
|
||||||
|
(state) => state.sampleDataResourceTokenCollection
|
||||||
|
),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -107,7 +113,11 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private getSplashScreenButtons = (): JSX.Element => {
|
private getSplashScreenButtons = (): JSX.Element => {
|
||||||
if (userContext.features.enableCopilot && userContext.apiType === "SQL") {
|
if (
|
||||||
|
useDatabases.getState().sampleDataResourceTokenCollection &&
|
||||||
|
userContext.features.enableCopilot &&
|
||||||
|
userContext.apiType === "SQL"
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<Stack style={{ width: "66%", cursor: "pointer", margin: "40px auto" }} tokens={{ childrenGap: 16 }}>
|
<Stack style={{ width: "66%", cursor: "pointer", margin: "40px auto" }} tokens={{ childrenGap: 16 }}>
|
||||||
<Stack horizontal tokens={{ childrenGap: 16 }}>
|
<Stack horizontal tokens={{ childrenGap: 16 }}>
|
||||||
@@ -137,7 +147,10 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
description={
|
description={
|
||||||
"Copilot is your AI buddy that helps you write Azure Cosmos DB queries like a pro. Try it using our sample data set now!"
|
"Copilot is your AI buddy that helps you write Azure Cosmos DB queries like a pro. Try it using our sample data set now!"
|
||||||
}
|
}
|
||||||
onClick={() => useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot)}
|
onClick={() => {
|
||||||
|
useTabs.getState().openAndActivateReactTab(ReactTabKind.QueryCopilot);
|
||||||
|
traceOpen(Action.OpenQueryCopilotFromSplashScreen, { apiType: userContext.apiType });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<SplashScreenButton
|
<SplashScreenButton
|
||||||
imgSrc={ConnectIcon}
|
imgSrc={ConnectIcon}
|
||||||
@@ -246,8 +259,9 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
<form className="connectExplorerFormContainer">
|
<form className="connectExplorerFormContainer">
|
||||||
<div className="splashScreenContainer">
|
<div className="splashScreenContainer">
|
||||||
<div className="splashScreen">
|
<div className="splashScreen">
|
||||||
<div
|
<h1
|
||||||
className="title"
|
className="title"
|
||||||
|
role="heading"
|
||||||
aria-label={
|
aria-label={
|
||||||
userContext.apiType === "Postgres"
|
userContext.apiType === "Postgres"
|
||||||
? "Welcome to Azure Cosmos DB for PostgreSQL"
|
? "Welcome to Azure Cosmos DB for PostgreSQL"
|
||||||
@@ -258,7 +272,7 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
|
|||||||
? "Welcome to Azure Cosmos DB for PostgreSQL"
|
? "Welcome to Azure Cosmos DB for PostgreSQL"
|
||||||
: "Welcome to Azure Cosmos DB"}
|
: "Welcome to Azure Cosmos DB"}
|
||||||
<FeaturePanelLauncher />
|
<FeaturePanelLauncher />
|
||||||
</div>
|
</h1>
|
||||||
<div className="subtitle">
|
<div className="subtitle">
|
||||||
{userContext.apiType === "Postgres"
|
{userContext.apiType === "Postgres"
|
||||||
? "Get started with our sample datasets, documentation, and additional tools."
|
? "Get started with our sample datasets, documentation, and additional tools."
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const SampleDataTree = ({
|
|||||||
const buildSampleDataTree = (): TreeNode => {
|
const buildSampleDataTree = (): TreeNode => {
|
||||||
const updatedSampleTree: TreeNode = {
|
const updatedSampleTree: TreeNode = {
|
||||||
label: sampleDataResourceTokenCollection.databaseId,
|
label: sampleDataResourceTokenCollection.databaseId,
|
||||||
isExpanded: true,
|
isExpanded: false,
|
||||||
iconSrc: CosmosDBIcon,
|
iconSrc: CosmosDBIcon,
|
||||||
className: "databaseHeader",
|
className: "databaseHeader",
|
||||||
children: [
|
children: [
|
||||||
@@ -47,6 +47,7 @@ export const SampleDataTree = ({
|
|||||||
{
|
{
|
||||||
label: "Items",
|
label: "Items",
|
||||||
onClick: () => sampleDataResourceTokenCollection.onDocumentDBDocumentsClick(),
|
onClick: () => sampleDataResourceTokenCollection.onDocumentDBDocumentsClick(),
|
||||||
|
contextMenu: ResourceTreeContextMenuButtonFactory.createSampleCollectionContextMenuButton(),
|
||||||
isSelected: () =>
|
isSelected: () =>
|
||||||
useSelectedNode
|
useSelectedNode
|
||||||
.getState()
|
.getState()
|
||||||
|
|||||||
@@ -131,6 +131,9 @@ export enum Action {
|
|||||||
LaunchUITour,
|
LaunchUITour,
|
||||||
CancelUITour,
|
CancelUITour,
|
||||||
CompleteUITour,
|
CompleteUITour,
|
||||||
|
OpenQueryCopilotFromSplashScreen,
|
||||||
|
OpenQueryCopilotFromNewQuery,
|
||||||
|
ExecuteQueryGeneratedFromQueryCopilot,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ActionModifiers = {
|
export const ActionModifiers = {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { guid } from "Explorer/Tables/Utilities";
|
||||||
import create, { UseStore } from "zustand";
|
import create, { UseStore } from "zustand";
|
||||||
|
|
||||||
interface QueryCopilotState {
|
interface QueryCopilotState {
|
||||||
@@ -6,9 +7,11 @@ interface QueryCopilotState {
|
|||||||
userPrompt: string;
|
userPrompt: string;
|
||||||
showFeedbackModal: boolean;
|
showFeedbackModal: boolean;
|
||||||
hideFeedbackModalForLikedQueries: boolean;
|
hideFeedbackModalForLikedQueries: boolean;
|
||||||
|
correlationId: string;
|
||||||
openFeedbackModal: (generatedQuery: string, likeQuery: boolean, userPrompt: string) => void;
|
openFeedbackModal: (generatedQuery: string, likeQuery: boolean, userPrompt: string) => void;
|
||||||
closeFeedbackModal: () => void;
|
closeFeedbackModal: () => void;
|
||||||
setHideFeedbackModalForLikedQueries: (hideFeedbackModalForLikedQueries: boolean) => void;
|
setHideFeedbackModalForLikedQueries: (hideFeedbackModalForLikedQueries: boolean) => void;
|
||||||
|
refreshCorrelationId: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useQueryCopilot: UseStore<QueryCopilotState> = create((set) => ({
|
export const useQueryCopilot: UseStore<QueryCopilotState> = create((set) => ({
|
||||||
@@ -17,9 +20,11 @@ export const useQueryCopilot: UseStore<QueryCopilotState> = create((set) => ({
|
|||||||
userPrompt: "",
|
userPrompt: "",
|
||||||
showFeedbackModal: false,
|
showFeedbackModal: false,
|
||||||
hideFeedbackModalForLikedQueries: false,
|
hideFeedbackModalForLikedQueries: false,
|
||||||
|
correlationId: "",
|
||||||
openFeedbackModal: (generatedQuery: string, likeQuery: boolean, userPrompt: string) =>
|
openFeedbackModal: (generatedQuery: string, likeQuery: boolean, userPrompt: string) =>
|
||||||
set({ generatedQuery, likeQuery, userPrompt, showFeedbackModal: true }),
|
set({ generatedQuery, likeQuery, userPrompt, showFeedbackModal: true }),
|
||||||
closeFeedbackModal: () => set({ generatedQuery: "", likeQuery: false, userPrompt: "", showFeedbackModal: false }),
|
closeFeedbackModal: () => set({ generatedQuery: "", likeQuery: false, userPrompt: "", showFeedbackModal: false }),
|
||||||
setHideFeedbackModalForLikedQueries: (hideFeedbackModalForLikedQueries: boolean) =>
|
setHideFeedbackModalForLikedQueries: (hideFeedbackModalForLikedQueries: boolean) =>
|
||||||
set({ hideFeedbackModalForLikedQueries }),
|
set({ hideFeedbackModalForLikedQueries }),
|
||||||
|
refreshCorrelationId: () => set({ correlationId: guid() }),
|
||||||
}));
|
}));
|
||||||
|
|||||||
Reference in New Issue
Block a user