add feedback policies integration with copilot (#1745)
* add feedback policies integration with copilot * remove teaching bubble and welcome modal * force prod phoenix endpoint in MPAC * force prod phoenix endpoint in MPAC
This commit is contained in:
parent
b3837a089d
commit
56c0049e9a
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"JUNO_ENDPOINT": "https://tools-staging.cosmos.azure.com",
|
"JUNO_ENDPOINT": "https://tools.cosmos.azure.com",
|
||||||
"isTerminalEnabled" : true,
|
"isTerminalEnabled": true,
|
||||||
"isPhoenixEnabled" : true
|
"isPhoenixEnabled": true
|
||||||
}
|
}
|
||||||
|
|
|
@ -407,6 +407,7 @@ export interface DataExplorerInputsFrame {
|
||||||
features?: {
|
features?: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
};
|
};
|
||||||
|
feedbackPolicies?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SelfServeFrameInputs {
|
export interface SelfServeFrameInputs {
|
||||||
|
|
|
@ -486,4 +486,4 @@ exports[`AddCollectionPanel should render Default properly 1`] = `
|
||||||
isButtonDisabled={false}
|
isButtonDisabled={false}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
`;
|
`;
|
|
@ -21,7 +21,6 @@ import {
|
||||||
import { HttpStatusCodes } from "Common/Constants";
|
import { HttpStatusCodes } from "Common/Constants";
|
||||||
import { handleError } from "Common/ErrorHandlingUtils";
|
import { handleError } from "Common/ErrorHandlingUtils";
|
||||||
import { createUri } from "Common/UrlUtility";
|
import { createUri } from "Common/UrlUtility";
|
||||||
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 {
|
import {
|
||||||
|
@ -272,28 +271,11 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showTeachingBubble = (): void => {
|
|
||||||
if (showPromptTeachingBubble && !inputEdited.current) {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!inputEdited.current && !isWelcomModalVisible()) {
|
|
||||||
setCopilotTeachingBubbleVisible(true);
|
|
||||||
inputEdited.current = true;
|
|
||||||
}
|
|
||||||
}, 30000);
|
|
||||||
} else {
|
|
||||||
toggleCopilotTeachingBubbleVisible(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleCopilotTeachingBubbleVisible = (visible: boolean): void => {
|
const toggleCopilotTeachingBubbleVisible = (visible: boolean): void => {
|
||||||
setCopilotTeachingBubbleVisible(visible);
|
setCopilotTeachingBubbleVisible(visible);
|
||||||
setShowPromptTeachingBubble(visible);
|
setShowPromptTeachingBubble(visible);
|
||||||
};
|
};
|
||||||
|
|
||||||
const isWelcomModalVisible = (): boolean => {
|
|
||||||
return localStorage.getItem("hideWelcomeModal") !== "true";
|
|
||||||
};
|
|
||||||
|
|
||||||
const clearFeedback = () => {
|
const clearFeedback = () => {
|
||||||
resetButtonState();
|
resetButtonState();
|
||||||
resetQueryResults();
|
resetQueryResults();
|
||||||
|
@ -322,7 +304,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
showTeachingBubble();
|
|
||||||
useTabs.getState().setIsQueryErrorThrown(false);
|
useTabs.getState().setIsQueryErrorThrown(false);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -539,84 +520,90 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
|
||||||
</Stack>
|
</Stack>
|
||||||
|
|
||||||
{showFeedbackBar && (
|
{showFeedbackBar && (
|
||||||
<Stack style={{ backgroundColor: "#FFF8F0", padding: "2px 8px" }} horizontal verticalAlign="center">
|
<Stack
|
||||||
<Text style={{ fontWeight: 600, fontSize: 12 }}>Provide feedback on the query generated</Text>
|
style={{ backgroundColor: "#FFF8F0", padding: "2px 8px", minHeight: 32 }}
|
||||||
{showCallout && !hideFeedbackModalForLikedQueries && (
|
horizontal
|
||||||
<Callout
|
verticalAlign="center"
|
||||||
role="status"
|
>
|
||||||
style={{ padding: 8 }}
|
{userContext.feedbackPolicies?.policyAllowFeedback && (
|
||||||
target="#likeBtn"
|
<Stack horizontal verticalAlign="center">
|
||||||
onDismiss={() => {
|
<Text style={{ fontWeight: 600, fontSize: 12 }}>Provide feedback on the query generated</Text>
|
||||||
setShowCallout(false);
|
{showCallout && !hideFeedbackModalForLikedQueries && (
|
||||||
SubmitFeedback({
|
<Callout
|
||||||
params: {
|
role="status"
|
||||||
generatedQuery: generatedQuery,
|
style={{ padding: 8 }}
|
||||||
likeQuery: likeQuery,
|
target="#likeBtn"
|
||||||
description: "",
|
onDismiss={() => {
|
||||||
userPrompt: userPrompt,
|
|
||||||
},
|
|
||||||
explorer,
|
|
||||||
databaseId,
|
|
||||||
containerId,
|
|
||||||
mode: isSampleCopilotActive ? "Sample" : "User",
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
directionalHint={DirectionalHint.topCenter}
|
|
||||||
>
|
|
||||||
<Text>
|
|
||||||
Thank you. Need to give{" "}
|
|
||||||
<Link
|
|
||||||
onClick={() => {
|
|
||||||
setShowCallout(false);
|
setShowCallout(false);
|
||||||
openFeedbackModal(generatedQuery, true, userPrompt);
|
SubmitFeedback({
|
||||||
|
params: {
|
||||||
|
generatedQuery: generatedQuery,
|
||||||
|
likeQuery: likeQuery,
|
||||||
|
description: "",
|
||||||
|
userPrompt: userPrompt,
|
||||||
|
},
|
||||||
|
explorer,
|
||||||
|
databaseId,
|
||||||
|
containerId,
|
||||||
|
mode: isSampleCopilotActive ? "Sample" : "User",
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
|
directionalHint={DirectionalHint.topCenter}
|
||||||
>
|
>
|
||||||
more feedback?
|
<Text>
|
||||||
</Link>
|
Thank you. Need to give{" "}
|
||||||
</Text>
|
<Link
|
||||||
</Callout>
|
onClick={() => {
|
||||||
|
setShowCallout(false);
|
||||||
|
openFeedbackModal(generatedQuery, true, userPrompt);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
more feedback?
|
||||||
|
</Link>
|
||||||
|
</Text>
|
||||||
|
</Callout>
|
||||||
|
)}
|
||||||
|
<IconButton
|
||||||
|
id="likeBtn"
|
||||||
|
style={{ marginLeft: 20 }}
|
||||||
|
aria-label="Like"
|
||||||
|
role="toggle"
|
||||||
|
iconProps={{ iconName: likeQuery === true ? "LikeSolid" : "Like" }}
|
||||||
|
onClick={() => {
|
||||||
|
setShowCallout(!likeQuery);
|
||||||
|
setLikeQuery(!likeQuery);
|
||||||
|
if (likeQuery === true) {
|
||||||
|
document.getElementById("likeStatus").innerHTML = "Unpressed";
|
||||||
|
}
|
||||||
|
if (likeQuery === false) {
|
||||||
|
document.getElementById("likeStatus").innerHTML = "Liked";
|
||||||
|
}
|
||||||
|
if (dislikeQuery) {
|
||||||
|
setDislikeQuery(!dislikeQuery);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
style={{ margin: "0 10px" }}
|
||||||
|
role="toggle"
|
||||||
|
aria-label="Dislike"
|
||||||
|
iconProps={{ iconName: dislikeQuery === true ? "DislikeSolid" : "Dislike" }}
|
||||||
|
onClick={() => {
|
||||||
|
let toggleStatusValue = "Unpressed";
|
||||||
|
if (!dislikeQuery) {
|
||||||
|
openFeedbackModal(generatedQuery, false, userPrompt);
|
||||||
|
setLikeQuery(false);
|
||||||
|
toggleStatusValue = "Disliked";
|
||||||
|
}
|
||||||
|
setDislikeQuery(!dislikeQuery);
|
||||||
|
setShowCallout(false);
|
||||||
|
document.getElementById("likeStatus").innerHTML = toggleStatusValue;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<span role="status" style={{ position: "absolute", left: "-9999px" }} id="likeStatus"></span>
|
||||||
|
<Separator vertical style={{ color: "#EDEBE9" }} />
|
||||||
|
</Stack>
|
||||||
)}
|
)}
|
||||||
<IconButton
|
|
||||||
id="likeBtn"
|
|
||||||
style={{ marginLeft: 20 }}
|
|
||||||
aria-label="Like"
|
|
||||||
role="toggle"
|
|
||||||
iconProps={{ iconName: likeQuery === true ? "LikeSolid" : "Like" }}
|
|
||||||
onClick={() => {
|
|
||||||
setShowCallout(!likeQuery);
|
|
||||||
setLikeQuery(!likeQuery);
|
|
||||||
if (likeQuery === true) {
|
|
||||||
document.getElementById("likeStatus").innerHTML = "Unpressed";
|
|
||||||
}
|
|
||||||
if (likeQuery === false) {
|
|
||||||
document.getElementById("likeStatus").innerHTML = "Liked";
|
|
||||||
}
|
|
||||||
if (dislikeQuery) {
|
|
||||||
setDislikeQuery(!dislikeQuery);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
style={{ margin: "0 10px" }}
|
|
||||||
role="toggle"
|
|
||||||
aria-label="Dislike"
|
|
||||||
iconProps={{ iconName: dislikeQuery === true ? "DislikeSolid" : "Dislike" }}
|
|
||||||
onClick={() => {
|
|
||||||
let toggleStatusValue = "Unpressed";
|
|
||||||
if (!dislikeQuery) {
|
|
||||||
openFeedbackModal(generatedQuery, false, userPrompt);
|
|
||||||
setLikeQuery(false);
|
|
||||||
toggleStatusValue = "Disliked";
|
|
||||||
}
|
|
||||||
setDislikeQuery(!dislikeQuery);
|
|
||||||
setShowCallout(false);
|
|
||||||
document.getElementById("likeStatus").innerHTML = toggleStatusValue;
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<span role="status" style={{ position: "absolute", left: "-9999px" }} id="likeStatus"></span>
|
|
||||||
|
|
||||||
<Separator vertical style={{ color: "#EDEBE9" }} />
|
|
||||||
<CommandBarButton
|
<CommandBarButton
|
||||||
className="copyQuery"
|
className="copyQuery"
|
||||||
onClick={copyGeneratedCode}
|
onClick={copyGeneratedCode}
|
||||||
|
@ -637,7 +624,6 @@ export const QueryCopilotPromptbar: React.FC<QueryCopilotPromptProps> = ({
|
||||||
</CommandBarButton>
|
</CommandBarButton>
|
||||||
</Stack>
|
</Stack>
|
||||||
)}
|
)}
|
||||||
<WelcomeModal visible={isWelcomModalVisible()} />
|
|
||||||
{isSamplePromptsOpen && <SamplePrompts sampleProps={sampleProps} />}
|
{isSamplePromptsOpen && <SamplePrompts sampleProps={sampleProps} />}
|
||||||
{query !== "" && query.trim().length !== 0 && (
|
{query !== "" && query.trim().length !== 0 && (
|
||||||
<DeletePopup
|
<DeletePopup
|
||||||
|
|
|
@ -53,6 +53,21 @@ interface FabricContext {
|
||||||
isReadOnly: boolean;
|
isReadOnly: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AdminFeedbackControlPolicy =
|
||||||
|
| "connectedExperiences"
|
||||||
|
| "policyAllowFeedback"
|
||||||
|
| "policyAllowSurvey"
|
||||||
|
| "policyAllowScreenshot"
|
||||||
|
| "policyAllowContact"
|
||||||
|
| "policyAllowContent"
|
||||||
|
| "policyEmailCollectionDefault"
|
||||||
|
| "policyScreenshotDefault"
|
||||||
|
| "policyContentSamplesDefault";
|
||||||
|
|
||||||
|
export type AdminFeedbackPolicySettings = {
|
||||||
|
[key in AdminFeedbackControlPolicy]: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
interface UserContext {
|
interface UserContext {
|
||||||
readonly fabricContext?: FabricContext;
|
readonly fabricContext?: FabricContext;
|
||||||
readonly authType?: AuthType;
|
readonly authType?: AuthType;
|
||||||
|
@ -84,6 +99,7 @@ interface UserContext {
|
||||||
collectionCreationDefaults: CollectionCreationDefaults;
|
collectionCreationDefaults: CollectionCreationDefaults;
|
||||||
sampleDataConnectionInfo?: ParsedResourceTokenConnectionString;
|
sampleDataConnectionInfo?: ParsedResourceTokenConnectionString;
|
||||||
readonly vcoreMongoConnectionParams?: VCoreMongoConnectionParams;
|
readonly vcoreMongoConnectionParams?: VCoreMongoConnectionParams;
|
||||||
|
readonly feedbackPolicies?: AdminFeedbackPolicySettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiType = "SQL" | "Mongo" | "Gremlin" | "Tables" | "Cassandra" | "Postgres" | "VCoreMongo";
|
export type ApiType = "SQL" | "Mongo" | "Gremlin" | "Tables" | "Cassandra" | "Postgres" | "VCoreMongo";
|
||||||
|
|
|
@ -499,6 +499,7 @@ function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) {
|
||||||
hasWriteAccess: inputs.hasWriteAccess ?? true,
|
hasWriteAccess: inputs.hasWriteAccess ?? true,
|
||||||
collectionCreationDefaults: inputs.defaultCollectionThroughput,
|
collectionCreationDefaults: inputs.defaultCollectionThroughput,
|
||||||
isTryCosmosDBSubscription: inputs.isTryCosmosDBSubscription,
|
isTryCosmosDBSubscription: inputs.isTryCosmosDBSubscription,
|
||||||
|
feedbackPolicies: inputs.feedbackPolicies,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (inputs.isPostgresAccount) {
|
if (inputs.isPostgresAccount) {
|
||||||
|
|
Loading…
Reference in New Issue